Java Date/Calendar oddness - java

I have a bit of (Java) that I where I am trying to simply subtract 7 days from the current date. It seemed to me like Calendar.add(..) should be the method to use (and what previous questions here seem to say), so that's what I tried:
SimpleDateFormat df = new SimpleDateFormat("dd-mm-yyyy");
GregorianCalendar cal = (GregorianCalendar) GregorianCalendar.getInstance();
System.out.println("ReportUtil.getDefaultReportStartDate cal: "+cal.toString() );
System.out.println("PRE ReportUtil.getDefaultReportStartDate: "+df.format(cal.getTime()) );
cal.add(Calendar.DATE, -7);
System.out.println("POST ReportUtil.getDefaultReportStartDate: "+df.format(cal.getTime()) );
That looks ok to me but you'll see from the output below the month field seems to go a bit... sideways! The day of the month/date seems to change correctly, but what is going on with the month?!
ReportUtil.getDefaultReportStartDate cal: java.util.GregorianCalendar[time=1330098699960,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="GB-Eire",offset=0,dstSavings=3600000,useDaylight=true,transitions=242,lastRule=java.util.SimpleTimeZone[id=GB-Eire,offset=0,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2012,MONTH=1,WEEK_OF_YEAR=8,WEEK_OF_MONTH=4,DAY_OF_MONTH=24,DAY_OF_YEAR=55,DAY_OF_WEEK=6,DAY_OF_WEEK_IN_MONTH=4,AM_PM=1,HOUR=3,HOUR_OF_DAY=15,MINUTE=51,SECOND=39,MILLISECOND=960,ZONE_OFFSET=0,DST_OFFSET=0]
PRE ReportUtil.getDefaultReportStartDate: 24-51-2012
POST ReportUtil.getDefaultReportStartDate: 17-51-2012

SimpleDateFormat df = new SimpleDateFormat("dd-mm-yyyy");
You get a strange month value because mm means minutes. Try:
SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy");
You can consult the whole list of the format symbols here: http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html

mm is the format string for Minute. You want MM

Your result seems to be correct.
The month is "1" in both dates of your first log line, which means February.
The "-mm-" in your SimpleDateFormat means minute and not month, thus the odd month of "51"

Related

Difference between kk and HH in date formatting java

I'm pretty new to java and am trying to format a time using 24 hour format. I've come across two ways of formatting the hour - HH and kk:
SimpleDateFormat format1 new SimpleDateFormat("HH:mm");
SimpleDateFormat format2 new SimpleDateFormat("kk:mm");
Date date = new Date();
System.out.println(format1.format(date));
System.out.println(format2.format(date));
These both produce something like 11:21. What's the difference between them? Am I missing something?
The two formats essentially do the same thing but differ in how they handle midnight. kk will format midnight to 24:00 whereas HH will format to 00:00. The hours in a day in k are 1-24 and in H are 0-23
It's always worth checking the java documentation as it generally provides very useful explanations as well as examples of uses.
try this to see the difference
SimpleDateFormat format1 = new SimpleDateFormat("HH:mm");
SimpleDateFormat format2 = new SimpleDateFormat("kk:mm");
Date date = new GregorianCalendar(2001, 0, 1, 0, 0 , 0 ).getTime();
System.out.println(format1.format(date));
System.out.println(format2.format(date));
output
00:00
24:00

Java SimpleDateFormat

I want to convert a date which may be several formats like yyyyMMdd,yyyy-MM-dd,yyyy/MM/dd to a standard for 'yyyy-MM-dd HH:mm:ss'. In the below code, I set the expected date format to 'yyyyMMdd' and then passed in '2014-02-21'. I was expecting a Parse Exception but some how this is returning '2013-12-02 00:00:00'.What am I missing here ?
SimpleDateFormat sdfSource = new SimpleDateFormat("yyyyMMdd");
Date date = sdfSource.parse("2014-02-21");
SimpleDateFormat sdfDestination = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println( sdfDestination.format(date));
I would recommend adding sdfSource.setLenient(false); between the first two lines of that snippet.
What's happening here is that "-0" is being interpreted as the month, and "2" as the day. With leniency true (which is the default) this is acceptable - "-0" is interpreted as the month before the first month; that is "December of the previous year".
The lenient property is set to true by default. here
sdfSource.setLenient(false);

Incrementing date by 18years in java

1.I want to set the setMaxSelectableDate=18years in JDateChooser so i provided it the date by incrementing milliseconds but how should i increment it by 18years.
2.Incrementing by 18years the calculation comes out to be 365*18*24*60*60*1000=56764800000 which gives me error integer number to large.
Date max=new Date();
Date oth1=new Date(max.getTime() + (365*18*24*60*60*1000)); //days*hours*minutes*seconds*milliseconds
SimpleDateFormat maxdateFormatter1 = new SimpleDateFormat("MMM d,yyyy hh:mm:ss a");
String maxdate=maxdateFormatter1.format(oth1);
DateChooser_V1.setMaxSelectableDate(new java.util.Date(maxdate));
Let java.util.Calendar do this work for you:
Calendar c = Calendar.getInstance();
c.setTime(oldDate);
c.add(Calendar.YEAR, 18);
Date newDate = c.getTime();
Which takes care of leap years, historical GMT offset changes, historical Daylight Saving Time schedule changes etc.
You need to use a long. You can achieve this by adding an L to your number:
365L* ...
With JodaTime
DateTime in18Years = new DateTime( ).plusYears( 18 );
Here is how to convert to java.util.Date
Date in18Years = new DateTime( ).plusYears( 18 ).toDate( );
You cannot willy-nilly add seconds (or millseconds) and expect calendar calculations to come out right. Basically it takes some extra effort to account for all of those leap-years, leap seconds, and daylight savings shifts.
Until Java 1.8 comes out, use java.util.Calendar instead of java.util.Date, there are really good reasons that java.util.Date has practically everything in it deprecated. While it looks good in the beginning, with enough use you will find it often "just doesn't work (tm)".
GregorianCalendar now = new GregorianCalendar();
now.add(Calendar.YEAR, 18);
And that's assuming that you didn't overflow Integer.MAX_INT.
I would use a Calendar object to achieve this:
Calendar cal = Calendar.getInstance();
Date dt = new Date();
...
// Set the date value
...
cal.setTime(dt);
cal.add(Calendar.YEAR, +18);
dt = cal.getTime();
Hope this helps you

How to get DAY of the WEEK from the datetime format in JAVA?

I have date time information in this format:
String reportDate="2012-04-19 12:32:24";
I want to have as output day of the week (Thursday or 4 as result anyway is good).
How to achieve this?
Thanks
Use the Calendar after parsing the string:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:SS");
Date d = sdf.parse(reportDate);
Calendar cal = Calendar.getInstance();
cal.setTime(d);
return cal.get(Calendar.DAY_OF_WEEK);
Use the SimpleDateFormat to parse the String then you have a Date object an can get the day of the week.
Parse your date to an actual Date Object and then pass it to a Calendar Instance (through setTime(Date date)). You can then use the DAY_OF_WEEK to get a number representing the days of the week.
Try,
System.out.println(new SimpleDateFormat("E").format(new SimpleDateFormat("yyyy-MM-dd").parse(reportDate)));
System.out.println(new SimpleDateFormat("F").format(new SimpleDateFormat("yyyy-MM-dd").parse(reportDate)));

Challenging Java/Groovy Date Manipulation

I have a bunch of dates formatted with the year and week, as follows:
2011-10
The week value is the week of the year(so 1-52). From this week value, I need to output something like the following:
Mar 7
Explicitly, I need the Month that the given week is in, and the date of the first Monday of that week. So in other words it is saying that the 10th week of the year is the week of March 7th.
I am using Groovy. What kind of date manipulation can I do to get this to work?
Here's a groovy solution:
use(groovy.time.TimeCategory) {
def (y, w) = "2011-10".tokenize("-")
w = ((w as int) + 1) as String
def d = Date.parse("yyyy-w", "$y-$w") + 1.day
println d.format("MMM dd")
}
Use a GregorianCalendar (or Joda, if you don't mind a dependency)
String date = "2011-10";
String[] parts = date.split("-");
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, Integer.parseInt(parts[0]));
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
cal.set(Calendar.WEEK_OF_YEAR, Integer.parseInt(parts[1])+1);
DateFormat df = new SimpleDateFormat("MMM d");
System.out.println(df.format(cal.getTime()) + " (" + cal.getTime() + ")");
EDIT: Added +1 to week, since calendar uses zero-based week numbers
Date date = new SimpleDateFormat("yyyy-w", Locale.UK).parse("2011-10");
System.out.println(new SimpleDateFormat("MMM d").format(date));
The first line returns first day of the 10th week in British Locale (March 7th). When Locale is not enforced, the results are dependent on default JVM Locale.
Formats are explained here.
You can use SimpleDateFormat, just like in java. See groovyconsole.appspot.com/script/439001
java.text.DateFormat df = new java.text.SimpleDateFormat('yyyy-w', new Locale('yourlocale'))
Date date = df.parse('2011-10')
To add a week, simply use Date date = df.parse('2011-10')+7
You don't need to set the Locale if your default Locale is using Monday as the first day of week.

Categories