1

I got a huge problem with converting my calendar objects to readable strings.

Actually I use df.format(cal.getTime()) to get a formatted string, this is not working quite well, because the Date object I get from cal.getTime() is not affected by timezones.

Please bite back any comments like "use joda time"...

I´m looking for a solution to convert directly from calendar objects to string.

These are my formatters:

  private DateFormat df = new SimpleDateFormat("HH:mm", Locale.GERMANY); // 13:42 Uhr
  private DateFormat df2 = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.GERMANY); // 14.04.2012

If you guys give this code a try, you will see that Date objects are not affected by timezones.

    //  this date is at wintertime
long milli = 1445945400000l;    //  CET  - central european time  

Calendar cal = Calendar.getInstance();

cal.setTimeInMillis(milli);
System.out.println("  ");
System.out.println("Kalender setTimeInMillis(" + milli + ");");
System.out.println("Daylight Time ? = " + cal.getTimeZone().useDaylightTime());
System.out.println("Date Time = " + cal.getTime());
System.out.println("Kalender Tag = " + cal.get(Calendar.DATE) + "  Monat = " + (cal.get(Calendar.MONTH) + 1) + "  Jahr = " + cal.get(Calendar.YEAR));
System.out.println("Kalender Uhrzeit = " + cal.get(Calendar.HOUR_OF_DAY) + ":" + cal.get(Calendar.MINUTE) + ":" + cal.get(Calendar.SECOND));

cal.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
System.out.println("  ");
System.out.println("Kalender setTimeZone(TimeZone.getTimeZone(\"Europe/Berlin\");");
System.out.println("Daylight Time ? = " + cal.getTimeZone().useDaylightTime());
System.out.println("Date Time = " + cal.getTime());
System.out.println("Kalender Tag = " + cal.get(Calendar.DATE) + "  Monat = " + (cal.get(Calendar.MONTH) + 1) + "  Jahr = " + cal.get(Calendar.YEAR));
System.out.println("Kalender Uhrzeit = " + cal.get(Calendar.HOUR_OF_DAY) + ":" + cal.get(Calendar.MINUTE) + ":" + cal.get(Calendar.SECOND));

    //  this date is at summertime
long milliS = 1445609700000l;   //  CEST - central european summertime

Calendar calS = Calendar.getInstance();

calS.setTimeInMillis(milliS);
System.out.println("  ");
System.out.println("Kalender setTimeInMillis(" + milliS + ");");
System.out.println("Daylight Time ? = " + calS.getTimeZone().useDaylightTime());
System.out.println("Date Time = " + calS.getTime());
System.out.println("Kalender Tag = " + calS.get(Calendar.DATE) + "  Monat = " + (calS.get(Calendar.MONTH) + 1) + "  Jahr = " + calS.get(Calendar.YEAR));
System.out.println("Kalender Uhrzeit = " + calS.get(Calendar.HOUR_OF_DAY) + ":" + calS.get(Calendar.MINUTE) + ":" + calS.get(Calendar.SECOND));

calS.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
System.out.println("  ");
System.out.println("Kalender setTimeZone(TimeZone.getTimeZone(\"Europe/Berlin\");");
System.out.println("Daylight Time ? = " + calS.getTimeZone().useDaylightTime());
System.out.println("Date Time = " + calS.getTime());
System.out.println("Kalender Tag = " + calS.get(Calendar.DATE) + "  Monat = " + (calS.get(Calendar.MONTH) + 1) + "  Jahr = " + calS.get(Calendar.YEAR));
System.out.println("Kalender Uhrzeit = " + calS.get(Calendar.HOUR_OF_DAY) + ":" + calS.get(Calendar.MINUTE) + ":" + calS.get(Calendar.SECOND));

OUTPUT

Kalender setTimeInMillis(1445945400000);  
Daylight Time ? = false  
Date Time** = Tue Oct 27 11:30:00 GMT 2015  
Kalender Tag = 27  Monat = 10  Jahr = 2015  
Kalender Uhrzeit = 11:30:0  

Kalender setTimeZone(TimeZone.getTimeZone("Europe/Berlin");  
Daylight Time ? = true  
Date Time = Tue Oct 27 11:30:00 GMT 2015  
Kalender Tag = 27  Monat = 10  Jahr = 2015  
Kalender Uhrzeit = 12:30:0  

Kalender setTimeInMillis(1445609700000);  
Daylight Time ? = false  
Date Time = Fri Oct 23 14:15:00 GMT 2015  
Kalender Tag = 23  Monat = 10  Jahr = 2015  
Kalender Uhrzeit = 14:15:0  

Kalender setTimeZone(TimeZone.getTimeZone("Europe/Berlin");  
Daylight Time ? = true  
Date Time = Fri Oct 23 14:15:00 GMT 2015  
Kalender Tag = 23  Monat = 10  Jahr = 2015  
Kalender Uhrzeit = 16:15:0
prototype0815
  • 592
  • 2
  • 7
  • 24

3 Answers3

1

You need to set the time zone of the formatter, a quick example:

SimpleDateFormat df = new SimpleDateFormat();

Calendar cal1 = Calendar.getInstance(TimeZone.getTimeZone("GMT+4:00"));

df.setTimeZone(cal1.getTimeZone());
System.out.println(df.format(cal1.getTime()));

Calendar cal2 = Calendar.getInstance(TimeZone.getTimeZone("GMT-3:00"));

df.setTimeZone(cal2.getTimeZone());
System.out.println(df.format(cal2.getTime()));

Output:

10/30/15 1:02 PM
10/30/15 6:02 AM
Pinkie Swirl
  • 2,375
  • 1
  • 20
  • 25
0

Be aware that java.util.Date objects do not contain any timezone information by themselves - you cannot set the timezone on a Date object. The only thing that a Date object contains is a number of milliseconds since the "epoch" - 1 January 1970, 00:00:00 UTC.

See https://stackoverflow.com/a/2892156/5445351

Community
  • 1
  • 1
0

Date Has Its Own Time Zone

Confusingly, a java.util.Date is assigned an internal time zone using the JVM's current default time zone. You cannot get or set that zone. The java.util.Calendar class was added to Java to handle time zone and other such issues.

Count From Epoch

long milli = 1445945400000l; // CET - central european time

Usually a number like that is a count-from-epoch in UTC (GMT), not any particular time zone. After creating a date-time object from that number you then assign a time zone to be applied.

Tip: Use an uppercase L on an integer literal to avoid looking like a 1 in many fonts.

java.time

These classes are now outmoded by the java.time framework built into Java 8 and later. The new classes are more sensible and easier to use.

Time Zone

A time zone is more than an offset-from-UTC. A time zone is an offset plus a set of past, present, and future rules for handling anomalies such as Daylight Saving Time. Use a proper time zone such as Europe/Berlin. Avoid using or even thinking about the 3-4 letter codes such as CET & CEST; they are neither standardized nor unique.

Example code

First we get an Instant, a moment on the timeline in UTC, from the count-from-epoch.

long milliSecondsFromEpochInUtc = 1445945400000L;
Instant instant = Instant.ofEpochMilli ( milliSecondsFromEpochInUtc );

Then we assign the desired time zone to get a ZonedDateTime.

ZoneId zoneId = ZoneId.of ( "Europe/Berlin" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId );

For output, a formatter by default uses the ZonedDateTime object’s assigned time zone.

DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime ( FormatStyle.MEDIUM ).withLocale ( Locale.GERMANY );
String output1 = zdt.format ( formatter );

Optionally a formatter may apply a different time zone if specified.

String output2 = zdt.format ( formatter.withZone ( ZoneId.of ( "America/Montreal" ) ) );

Dump to console.

System.out.println ( "instant (UTC): " + instant );
System.out.println ( "zdt: " + zdt );
System.out.println ( "Berlin time zone: " + output1 );
System.out.println ( "Montréal time zone: " + output2 );

When run. Note that all of these represent the same moment on the timeline. Their presentation varies but they all mean the same simultaneous moment.

instant (UTC): 2015-10-27T11:30:00Z
zdt: 2015-10-27T12:30+01:00[Europe/Berlin]
Berlin time zone: 27.10.2015 12:30:00
Montréal time zone: 27.10.2015 07:30:00
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154