2

I'm trying to get my local time, when it's midnight in a different timezone. What I mean is:

  • What time is it in Stockholm, when it's midnight in London?
  • What time is it in Stockholm, when it's midnight in Helsinki?

Here is the code I have

public static void main(String[] args) throws ParseException {
    DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
    formatter.setTimeZone(TimeZone.getTimeZone("Europe/Stockholm"));
    Date date = formatter.parse("2013-04-13 00:00:00.000");

    System.out.println("London: " + formatter.format(getFirstInstantOfDay("Europe/London", date)));
    System.out.println("Helsinki: " + formatter.format(getFirstInstantOfDay("Europe/Helsinki", date)));
}

public static Date getFirstInstantOfDay(String timeZoneId, Date date) {
    Calendar resultDate = Calendar.getInstance(TimeZone.getTimeZone(timeZoneId));
    resultDate.setTime(date);
    resultDate.set(Calendar.HOUR, 0);
    resultDate.set(Calendar.MINUTE, 0);
    resultDate.set(Calendar.SECOND, 0);
    resultDate.set(Calendar.MILLISECOND, 0);
    return resultDate.getTime();
}

The output is:

London: 2013-04-12 13:00:00.000
Helsinki: 2013-04-12 23:00:00.000

And I expected:

London: 2013-04-13 01:00:00.000
Helsinki: 2013-04-12 23:00:00.000

For Helsinki the result is as expected, but for London is this crazy result that I don't understand where it comes from.

----- EDIT -----

Final code with the expected output:

String dateStr = "2013-04-13";

DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
formatter.setTimeZone(TimeZone.getTimeZone("Europe/London"));
Date dateGB = formatter.parse(dateStr);
formatter.setTimeZone(TimeZone.getTimeZone("Europe/Stockholm"));
Date dateSE = formatter.parse(dateStr);
formatter.setTimeZone(TimeZone.getTimeZone("Europe/Helsinki"));
Date dateFI = formatter.parse(dateStr);

DateFormat stockholmFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
stockholmFormatter.setTimeZone(TimeZone.getTimeZone("Europe/Stockholm"));


System.out.println("Midnight in London is " + stockholmFormatter.format(dateGB) + " in Stockholm.");
System.out.println("Midnight in Stockholm is " + stockholmFormatter.format(dateSE) + " in Stockholm.");
System.out.println("Midnight in Helsinki is " + stockholmFormatter.format(dateFI) + " in Stockholm.");

Output:

Midnight in London is 2013-04-13 01:00:00.000 in Stockholm.
Midnight in Stockholm is 2013-04-13 00:00:00.000 in Stockholm.
Midnight in Helsinki is 2013-04-12 23:00:00.000 in Stockholm.
Kai
  • 38,985
  • 14
  • 88
  • 103
Oliveira
  • 1,281
  • 1
  • 11
  • 19
  • 1
    Why do you start by parsing the date in the Stockholm timezone? That doesn't make sense to me. And clearly you are using the `HOUR` field where you should be using `HOUR_OF_DAY`. – Marko Topolnik Apr 13 '13 at 12:49
  • How would it make sense to you, then? – Oliveira Apr 13 '13 at 12:59
  • 2
    Don't you first want to choose the midnight of a specific date in another timezone and then reinterpret that instant in your timezone? What you are doing now is not achieving that goal. – Marko Topolnik Apr 13 '13 at 13:04

3 Answers3

3

Try changing Hour to HOUR_OF_DAY. It appears to be reading time once as AM and once as PM.

more info: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Calendar.html

Xyzk
  • 1,332
  • 2
  • 21
  • 36
  • The HOUR_OF_DAY fixed the hour problem, but the day is still 12, when it should be 13: "London: 2013-04-12 01:00:00.000" – Oliveira Apr 13 '13 at 12:57
  • Try editing your code like this: http://stackoverflow.com/questions/7670355/convert-date-time-for-given-timezone-java – Xyzk Apr 13 '13 at 13:07
2

Calender has two ways of setting the hour of the day.

The first way is via HOUR_OF_DAY :

resultDate.set(Calendar.HOUR_OF_DAY, 0);

The second option is via 'HOUR' and 'AM_PM'

resultDate.set(Calendar.HOUR, 0);
resultDate.set(Calendar.AM_PM,Calendar.AM);

EDIT: The fact that you get 2013-04-12 is correct.

You enter 2013-04-13 00:00:00.000 in Stockholm

This is the same time as 2013-04-12 23:00:00.000 in London

You then reset the hour to 00, yielding 2013-04-12 00:00:00.000 in London

Then going back to Stockholm time yields

2013-04-12 01:00:00.000

When you do the test (at 2013-04-13 00:00:00.00 in Stockholm) London is still in the previous day (2013-04-12).

EDIT

What you probably want to know is when midnight occurs (expressed in Stockholm time) in various cities. I would go for something like this:

public static void main(String[] args) throws ParseException {
    DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
    formatter.setTimeZone(TimeZone.getTimeZone("Europe/Stockholm"));

    String date = "2013-04-13";
    System.out.println("Stockholm: " + formatter.format(getMidnightTime("Europe/Stockholm", date)));
    System.out.println("London:    " + formatter.format(getMidnightTime("Europe/London", date)));
    System.out.println("Helsinki:  " + formatter.format(getMidnightTime("Europe/Helsinki", date)));
}

public static Date getMidnightTime(String timeZoneId, String date) throws ParseException {
    DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
    formatter.setTimeZone(TimeZone.getTimeZone(timeZoneId));
    return formatter.parse(date);
}


Stockholm: 2013-04-13 00:00:00.000
London:    2013-04-13 01:00:00.000
Helsinki:  2013-04-12 23:00:00.000
DeltaLima
  • 5,864
  • 1
  • 16
  • 32
  • The HOUR_OF_DAY fixed the Hour, but not the day. The output is still: "London: 2013-04-12 01:00:00.000" – Oliveira Apr 13 '13 at 13:04
1

You are parsing the date with the stockolm time zone:

formatter.setTimeZone(TimeZone.getTimeZone("Europe/Stockholm"));

and the result date you parse to London time zone and to helsinki:

 DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
 formatter.setTimeZone(TimeZone.getTimeZone("Europe/London"));
 Date date = formatter.parse("2013-04-13 00:00:00.000");
 System.out.println("London: " + formatter.format(getFirstInstantOfDay("Europe/London",  date)));
 System.out.println("Helsinki: " + formatter.format(getFirstInstantOfDay("Europe/Helsinki", date)));

the result is:

London: 2013-04-13 00:00:00.000
Helsinki: 2013-04-12 22:00:00.000

Note that your format has HH that means hour from 0 to 23.

* edit *

To get the time at London, stockholm and Helsinky:

formatter.setTimeZone(TimeZone.getTimeZone("Europe/London"));
Date date = formatter.parse("2013-04-13 00:00:00.000");

System.out.println("London: " + formatter.format(date));                    
formatter.setTimeZone(TimeZone.getTimeZone("Europe/Stockholm"));
System.out.println("Stockolm: " + formatter.format(date));
formatter.setTimeZone(TimeZone.getTimeZone("Europe/Helsinki"));
System.out.println("Helsinki: " + formatter.format(date));

And the output is:

London: 2013-04-13 00:00:00.000
Stockolm: 2013-04-13 01:00:00.000
Helsinki: 2013-04-13 02:00:00.000
Joan
  • 427
  • 3
  • 6
  • I want the output to be in Stockholm timezone, not in London timezone. Of course it's midnight in London when it's midnight in London. But it's 1AM in Stockholm, when it's midnight in London, and that's what I'm trying to get. – Oliveira Apr 13 '13 at 13:02