I am using the following code
Calendar cal = Calendar.getInstance();
System.out.println("Before "+cal.getTime());
cal.set(Calendar.MONTH, 01);
System.out.println("After "+cal.getTime());
the output is
Before Thu Jan 31 10:07:34 IST 2013
After Sun Mar 03 10:07:34 IST 2013
for adding +1 to jan is giving mar month. may be it returning correct output if we add 30 days to present date. but i want to show feb month. can any body help me please..
you can see the +1 to set field is adding 30 days date different to your dates(observed from your output.)
if you want months then use the code
Calendar cal = Calendar.getInstance();
System.out.println("Before "+cal.getTime()); //Before Thu Jan 31 10:16:23 IST 2013
cal.add(Calendar.MONTH, 1);
System.out.println("After "+cal.getTime()); //After Thu Feb 28 10:16:23 IST 2013
You have to use add() like,
cal.add(Calendar.MONTH, 1);
OUTPUT ->
Before Thu Jan 31 10:15:04 IST 2013
After Thu Feb 28 10:15:04 IST 2013
This kind of date-time work is easier using either:
Joda-Time 2.3 library
Popular replacement for the java.util.Date & .Calendar classes bundled with Java
Open source
Free of cost
Actively maintained (as of 2014-02)
java.time package
New in Java 8
Inspired by Joda-Time, but re-architected
Defined by JSR 310
Tutorial available
Example Code
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" ); // Or, DateTimeZone.UTC
DateTime dateTime = new DateTime( timeZone );
DateTime monthAgo = dateTime.plusMonths( -1 ); // Smartly handles various month lengths, leap year, and so on.
DateTime monthLater = dateTime.plusMonths( 1 );
Dump to console…
System.out.println( "dateTime: " + dateTime );
System.out.println( "monthAgo: " + monthAgo );
System.out.println( "monthAgo start of day: " + monthAgo.withTimeAtStartOfDay() );
System.out.println( "monthLater: " + monthLater );
When run…
dateTime: 2014-02-24T01:53:22.386+01:00
monthAgo: 2014-01-24T01:53:22.386+01:00
monthAgo start of day: 2014-01-24T00:00:00.000+01:00
monthLater: 2014-03-24T01:53:22.386+01:00
cal.set(Calendar.MONTH, cal.get( Calendar.MONTH ) + 1 );
The reason it shows Mar 3 anyway, is because it apparently adds 30 days, which is Feb 31st which does not exist, so it goes to Mar 3.
If you wanted the last day of the next month instead, you would do something like this:
int month = cal.get( Calendar.MONTH );
cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) + 1);
if( cal.get( month ) > month + 1 ) {
cal.set( Calendar.MONTH, month + 1 );
cal.set( Calendar.DAY, /* here comes your day amount finding algorithm */ );
}
Related
I have date formats as: EEE, dd MMM yyyy HH:mm:ss Z
For ex.,
Date 1 : Mon Sep 10 08:32:58 GMT 2018
Date 2 : Tue Sep 11 03:56:10 GMT 2018
I need date difference as 1 in above case, but I am getting value as 0 if I use joda date time or manually converting date to milliseconds.
For reference : http://www.mkyong.com/java/how-to-calculate-date-time-difference-in-java/
Any leads will be helpful.
Example :
Date date1 = new Date("Mon Sep 10 08:32:58 GMT 2018");
Date date2 = new Date("Tue Sep 11 03:56:10 GMT 2018");
DateTime start = new DateTime(date1 );
DateTime end = new DateTime(date2);
int days = Days.daysBetween(start, end).getDays();
System.out.println("Date difference: " + days);
Output: Date difference: 0
Joda-Time counts only whole days, in other words, truncates the difference to a whole number. So with a little over 19 hours between your values it counts as 0 days. If you want to ignore the time part of the dates, convert to LocalDate first:
int days = Days.daysBetween(start.toLocalDate(), end.toLocalDate()).getDays();
(Thanks for providing the concrete code yourself in a comment. Since you said it worked, I thought it deserved to be an answer.)
As mentioned in previous comments, Joda-Time counts whole days and rounds down. Therefore you'll need to skip the time when comparing. Something like this will work, using Java.time comparing the dates:
Date date1 = new Date("Mon Sep 10 08:32:58 GMT 2018");
Date date2 = new Date("Tue Sep 11 03:56:10 GMT 2018");
LocalDate start = date1.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate end = date2.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
long between = ChronoUnit.DAYS.between(start, end);
System.out.println("Date difference: " + between);
I am having an issue with Dates and timezones.
I have a MySQL InnoDB database which holds two fields DATE(yyyy-MM-dd) and TIME(HH:mm:ss). These are known as to be UTC (0 GMT). My computer is based in CET (+1 GMT).
• dateObject is the result from this resultSet.getTime("date_field") (java.sql.Date)
• timeObject is a result from this resultSet.getDate("time_field") (java.sql.Time)
In the database DATE is stored as 2014-02-22 and TIME 15:00
System.out.println("Untouched "+dateObject+" "+timeObject);
long date = dateObject.getTime();
long time = timeObject.getTime();
System.out.println("Touched "+new Date(date+time));
Results in the following output:
Untouched 2014-02-22 15:00:00
Touched Sat Feb 22 14:00:00 CET 2014
Why is one hour being skipped off the Touched output? I was expecting the following:
Untouched 2014-02-22 15:00:00
Touched Sat Feb 22 15:00:00 CET 2014
To rumble things up I have tried with the following also:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.format(new Date(date+time)));
And result:
2014-02-22 14:00:00
All in all. I am expecting GMT+1 to show 16:00(local) and GMT+0 to display 15:00
I think I did answer ma question (Remember timeObject in the db is 15:00:00 at UTC):
TimeZone tz = TimeZone.getTimeZone("Gmt0");
SimpleDateFormat sdfFull = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdfFull.setTimeZone(tz);
Date updateDate = sdfFull.parse(dateObject.toString()+" "+timeObject.toString());
System.out.println(updateDate);
Results in what I was hoping for:
Sat Feb 22 16:00:00 CET 2014
The reason is similar to this SO-answer. But note following details about toString().
java.util.Date.toString() => output dependent on your system time zone
in format pattern "EEE MMM dd HH:mm:ss zzz yyyy"
java.sql.Date.toString() => output in format "yyyy-MM-dd" (your dateObject)
java.sql.Time.toString() => output in format "HH:mm:ss" (your timeObject)
The sql representations are not dependent on time zone. So you compare apples and peaches.
Supplementary remark:
I have invested more in testing and found:
java.sql.Date dateObj = new java.sql.Date(2014 - 1900, Calendar.FEBRUARY, 22);
Time timeObj = new Time(15, 0, 0);
Time midnight = new Time(0, 0, 0);
Date d = new Date(dateObj.getTime() + timeObj.getTime());
System.out.println("dateObj: " + dateObj + "/" + dateObj.getTime());
// dateObj: 2014-02-22/1393023600000, one hour less than a full day because of UTC-long
System.out.println("timeObj: " + timeObj + "/" + timeObj.getTime());
// timeObj: 15:00:00/50400000 => one hour less as UTC-long
System.out.println("midnight: " + midnight + "/" + midnight.getTime());
// midnight: 00:00:00/-3600000 => one hour less, negative!
System.out.println(new Date(dateObj.getTime())); // Sat Feb 22 00:00:00 CET 2014
System.out.println(new Date(timeObj.getTime())); // Thu Jan 01 15:00:00 CET 1970
System.out.println(d); // Sat Feb 22 14:00:00 CET 2014
So I strongly suspect following effect: Both dateObject and timeObject are been calculated your system time zone, therefore their utc-long values show both one hour less - the time zone offset. If you combine both in one Date-object by just summarizing up then one of both deltas gets lost because one single date object cannot take in account two offsets.
Conclusion: You tried to combine date and time by summarize their utc-longs, but this is in general a faulty approach. Date plus Date is not Date, but undefined! In domain-specific language you can only add a duration/period to a date/time. So a solution having a midnight object could be:
Date d = new Date(dateObj.getTime() + timeObj.getTime() - midnight.getTime());
System.out.println(d); // Sat Feb 22 15:00:00 CET 2014, correct - what you wanted
Aim: to fetch the next seven days (including the current day).
I am using add(int field, int value) method of the Calendar class.
Code:
Calendar cal = Calendar.getInstance();
for (int i = 0; i < 7; i++){
int index = cal.get(Calendar.DAY_OF_WEEK) - 1;
String text = cal.get(Calendar.DATE) + " " +cal.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.getDefault());
cal.add(cal.get(Calendar.DAY_OF_MONTH), 1);
Log.d(TAG, text);
}
Throws IllegalArgumentException.
According to the docs, this exception is thrown if the field is ZONE_OFFSET or DST_OFFSET.
Logcat:
E/AndroidRuntime(17841): Caused by: java.lang.IllegalArgumentException
E/AndroidRuntime(17841): at java.util.GregorianCalendar.add(GregorianCalendar.java:357)
You should be using
cal.add(Calendar.DAY_OF_MONTH, 1);
The first parameter of that method is the date field to add to.
You were passing the value of that field as the field identifier. It was probably over the value of ZONE_OFFSET.
The answer by Sotirios Delimanolis is correct.
FYI, this kind of date-time work is easier with the Joda-Time library.
Here is some example code using Joda-Time 2.3 and Java 7. I used a Paris time zone and a France locale, but you can replace with your own.
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;
// Specify time zone rather than rely on default.
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
// Joda-Time offers many formatters, plus you may define your own.
// Using "forStyle" approach, pass first letter of the word Short/Medium/Long/Full, first for date and then for time.
DateTimeFormatter formatter = DateTimeFormat.forStyle( "MM" ).withLocale( Locale.FRANCE ).withZone( timeZone );
DateTime now = new DateTime( timeZone );
for (int i = 0; i < 7; i++){
DateTime dateTime = now.plusDays( i );
// Extract descriptions.
String dayOfWeekAsText = dateTime.dayOfWeek().getAsText( Locale.FRANCE );
String monthAsText = dateTime.monthOfYear().getAsText( Locale.FRANCE );
String dateTimeAsText = formatter.print( dateTime );
// Dump to console.
System.out.println( "dayOfWeekAsText: " + dayOfWeekAsText );
System.out.println( "monthAsText: " + monthAsText );
System.out.println( "dateTimeAsText: " + dateTimeAsText );
System.out.println(); // Blank line.
}
When run…
dayOfWeekAsText: lundi
monthAsText: janvier
dateTimeAsText: 6 janv. 2014 18:35:18
dayOfWeekAsText: mardi
monthAsText: janvier
dateTimeAsText: 7 janv. 2014 18:35:18
dayOfWeekAsText: mercredi
monthAsText: janvier
dateTimeAsText: 8 janv. 2014 18:35:18
dayOfWeekAsText: jeudi
monthAsText: janvier
dateTimeAsText: 9 janv. 2014 18:35:18
dayOfWeekAsText: vendredi
monthAsText: janvier
dateTimeAsText: 10 janv. 2014 18:35:18
dayOfWeekAsText: samedi
monthAsText: janvier
dateTimeAsText: 11 janv. 2014 18:35:18
dayOfWeekAsText: dimanche
monthAsText: janvier
dateTimeAsText: 12 janv. 2014 18:35:18
I was Suffering on the same issue before I found simple way of doing it, just use the Roll method of Calendar Instance and it will increment date by one or you can specify amount for increment, in steady of true put day interval, negative for decrements. in kotlin is done like this #codes below
val calendar = Calendar.getInstance()
for(i in 0..6){
calendar.roll(Calendar.DATE,true)
println(getDateInstance().format(calendar.time))
}
and the result is like
I/System.out: Jun 11, 2019
I/System.out: Jun 12, 2019
I/System.out: Jun 13, 2019
I/System.out: Jun 14, 2019
I/System.out: Jun 15, 2019
I/System.out: Jun 16, 2019
I/System.out: Jun 17, 2019
hope it helps
use following code
class CalenderService extends AsyncTask
{
#Override
protected void onPreExecute() {
super.onPreExecute();
DayList=new ArrayList<>();
}
#Override
protected Object doInBackground(Object[] params) {
SimpleDateFormat sdf = new SimpleDateFormat("EEE");
Date d = new Date();
for (int i=0;i<7;i++)
{
Calendar cal=Calendar.getInstance();
cal.setTime(d);
cal.add(Calendar.DAY_OF_WEEK,i);
Date dayweek=cal.getTime();
String NextDay=sdf.format(dayweek);
int nxtday=dayweek.getDate();
ED=new Everydays(nxtday,NextDay);
DayList.add(ED);
}
return null;
}
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
for (int i=0;i<DayList.size();i++)
{
Toast.makeText(getApplicationContext(),String.valueOf(DayList.get(i).nxtday)+" "+DayList.get(i).nextDay,Toast.LENGTH_SHORT).show();
}
}
}
I manage some dates in my own date classes. I want to create a method like this in my date:
int getWeekdayIndex()
right now it lookes something like this:
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
cal.set(year, month+1, day); // data of this date
int weekdayIndex = cal.get(Calendar.DAY_OF_WEEK);
return weekdayIndex;
I know DAY_OF_WEEK returns 1(Sunday) to 7(Saturday), but if I test this method with
2014-01-06 I get index 5 (suppost to be 2)
2014-01-07 I get index 6 (suppost to be 3)
(I live in Berlin UTC+01:00 - if it matters)
You should use:
cal.set(year, month-1, day); // data of this date
Do note the month-1 part instead of month+1.
Assuming that month's value is:
1 for Jan
2 for Feb
3 for Mar
...
What is month in your scenario? If it's 0 for "January", you are adding 1 when calling the set method. But months in Java are zero-based, so you're setting "February", and February 6th, 2014 is a Thursday (5), and February 7th, 2014 is a Friday (6).
month - the value used to set the MONTH calendar field. Month value is 0-based. e.g., 0 for January.
Try changing
cal.set(year, month+1, day);
to
cal.set(year, month, day);
FYI, Joda-Time 2.3 has convenient methods for such work.
The DateTime class offers a dayOfWeek method. From that you can derive either the localized name of the day, and to your needs, the number. Joda-Time counts days using the international standard ISO 8601, where Monday is 1 and Sunday is 7.
Example code…
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
DateTimeZone berlinTimeZone = DateTimeZone.forID( "Europe/Berlin" );
DateTime dateTime = new DateTime( 2013, DateTimeConstants.DECEMBER, 13, 14, 15, 16, berlinTimeZone );
String dayOfWeekAsText = dateTime.dayOfWeek().getAsText( Locale.GERMANY );
int dayOfWeekAsNumber = dateTime.dayOfWeek().get();
System.out.println( "dayOfWeekAsText: " + dayOfWeekAsText );
System.out.println( "dayOfWeekAsNumber: " + dayOfWeekAsNumber );
When run…
dayOfWeekAsText: Freitag
dayOfWeekAsNumber: 5
Easy to jump to another month.
DateTime previousMonthDateTime = dateTime.minusMonths( 1 );
DateTime nextMonthDateTime = dateTime.plusMonths( 1 );
when I want to sum two dates in java it does not work:
System.out.println(date + " <---- date");
System.out.println(time + " <---- time");
System.out.println(new Date(date.getTime() + time.getTime()) + " <---- new Date(time.getTime() + date.getTime())");
leads to following output:
Wed Nov 06 00:00:00 CET 2013 <---- date
Thu Jan 01 11:51:14 CET 1970 <---- time
Wed Nov 06 10:51:14 CET 2013 <---- new Date(time.getTime() + date.getTime())
... but if i work with Calender it works!
Calendar calendar = Calendar.getInstance();
calendar.setTime(time);
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int min = calendar.get(Calendar.MINUTE);
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, min);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
Date myDate = calendar.getTime();
System.out.println(myDate);
results in
Wed Nov 06 11:51:00 CET 2013
which is correct
Can anybody explain me why?
Fundamentally, you've got problems with time zones here. The fact that you're using a java.util.Date to represent a time of day is messing you up to start with. Your time of 11:51:14 CET is actually 10:51:14 UTC, so when you add the result of calling time.getTime(), you're only adding "just under 11 hours" rather than "just under 12 hours". The use of inappropriate data types makes all this hard to work with and understand.
I'd strongly recommend using Joda Time for all of this. Then you can start with a LocalDate and LocalTime, combine them into a LocalDateTime and then work out if you want to apply a particular time zone.
Using the right data types, which mean exactly what you're trying to convey, makes a huge difference for date/time work.