Convert date / time for a given time zone - java

I want to convert this GMT timestamp to GMT + 13:

2011-10-06 03:35:05 

I tried about 100 different combinations of DateFormat, TimeZone, Date, GregorianCalendar, etc. to try to do this VERY main task.

This code does what I want for CURRENT TIME:

 Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("GMT")); DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z"); formatter.setTimeZone(TimeZone.getTimeZone("GMT+13")); String newZealandTime = formatter.format(calendar.getTime()); 

But I want to set the time, not use the current time.

I found that at any time I try to set such a time:

 calendar.setTime(new Date(1317816735000L)); 

The local TimeZone machine is used. Why is this? I know that when "new Date ()" returns UTC + 0, why, when you set Time in milliseconds, is it no longer supposed to be time in UTC?

Maybe:

  • Set the time for the object (Calendar / Date / Time)
  • (possibly) Set the time interval of the initial timestamp (calendar.setTimeZone (...))
  • Mark the timestamp with a new TimeZone (formatter.setTimeZone (...)))
  • Returns a string with a new time zone. (Formatter.format (calendar.getTime ()))

Thanks in advance for your help: D

+63
java timezone datetime timestamp formatting
Oct 06
source share
17 answers

For me, the easiest way to do this is:

 Calendar calendar = Calendar.getInstance(); calendar.setTime(new Date()); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); //Here you say to java the initial timezone. This is the secret sdf.setTimeZone(TimeZone.getTimeZone("UTC")); //Will print in UTC System.out.println(sdf.format(calendar.getTime())); //Here you set to your timezone sdf.setTimeZone(TimeZone.getDefault()); //Will print on your default Timezone System.out.println(sdf.format(calendar.getTime())); 
+42
Mar 12
source share

Understanding how computer time works is very important. With that said, I agree that if the API is designed to help you handle computer time like in real time, then it should work in such a way that you can treat it like in real time. For the most part this is true, but there are some basic flaws that need attention.

In any case, I'm distracted! If you have a UTC offset (working better in UTC than GMT offset), you can calculate the time in milliseconds and add it to the timestamp. Please note that the SQL timestamp may differ from the Java timestamp, since the method for calculating the time from the epoch is not always the same - it depends on database technologies, as well as on operating systems.

I would advise using System.currentTimeMillis () as your timestamps, as they can be processed more consistently in java without worrying about converting SQL timestamps to java Date objects, etc.

To calculate the offset, you can try something like this:

 Long gmtTime =1317951113613L; // 2.32pm NZDT Long timezoneAlteredTime = 0L; if (offset != 0L) { int multiplier = (offset*60)*(60*1000); timezoneAlteredTime = gmtTime + multiplier; } else { timezoneAlteredTime = gmtTime; } Calendar calendar = new GregorianCalendar(); calendar.setTimeInMillis(timezoneAlteredTime); DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z"); formatter.setCalendar(calendar); formatter.setTimeZone(TimeZone.getTimeZone(timeZone)); String newZealandTime = formatter.format(calendar.getTime()); 

I hope this will be helpful!

+30
09 Oct '11 at 20:45
source share

As always, I recommend reading this article about date and time in Java so that you understand it.

The basic idea is that “under the hood” everything is done in UTC milliseconds from the era. This means that this is easiest if you work without using time zones at all, except for formatting the string for the user.

Therefore, I would skip most of the steps you suggested.

  • Set the time for the object (date, calendar, etc.).
  • Set the time zone for the formatting object.
  • Returns a string from formatting.

Alternatively, you can use Joda time . I heard that this is a much more intuitive datetime API.

+23
06 Oct 2018-11-11T00:
source share

TL; dr

 Instant.ofEpochMilli( 1_317_816_735_000L ) .atZone( ZoneId.of( "Pacific/Auckland" ) ) .format( DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM ).withLocale( new Locale( "en" , "NZ" ) ) ) 

…also…

 LocalDateTime.parse( "2011-10-06 03:35:05".replace( " " , "T" ) ) .atZone( ZoneId.of( "Pacific/Auckland" ) ) 

java.time

The Question and most Answers use legacy date and time classes from the earliest versions of Java. These old classes were unpleasant and confusing. Avoid them. Use java.time classes instead.

ISO 8601

Your input string is almost in the standard ISO 8601 format. Just replace the SPACE in the middle with the letter T

 String input = "2011-10-06 03:35:05".replace( " " , "T" ); 

LocalDateTime

Now analyze as LocalDateTime because there is no input information about the offset from UTC or time zone. LocalDateTime has no notion of offset or time zone, so it does not represent the actual moment in the timeline.

 LocalDateTime ldt = LocalDateTime.parse( input ); 

ZoneOffset

You seem to be saying that from the business context, you know that this line is intended to represent a moment that is 13 hours ahead of UTC. So we create an instance of ZoneOffset .

 ZoneOffset offset = ZoneOffset.ofHours( 13 ); // 13 hours ahead of UTC, in the far east of the globe. 

OffsetDateTime

Apply it to get an OffsetDateTime object. This is becoming a moment in time.

 OffsetDateTime odt = ldt.atOffset( offset); 

ZoneId

But then you mention New Zealand. So you meant a specific time zone. The time zone is an offset from UTC plus a set of rules for handling anomalies such as Daylight Saving Time (DST). So we can specify the ZoneId for the ZonedDateTime and not just the offset.

Please enter a valid time zone name . Never use a 3-4-letter abbreviation, such as EST or IST as they are not true time zones, are not standardized, and are not even unique (!). For example, Pacific/Auckland .

 ZoneId z = ZoneId.of( "Pacific/Auckland" ); 

ZonedDateTime

Apply ZoneId .

 ZonedDateTime zdt = ldt.atZone( z ); 

You can easily switch to another zone at the same time on the timeline.

 ZoneId zParis = ZoneId.of( "Europe/Paris" ); ZonedDateTime zdtParis = zdt.withZoneSameInstant( zParis ); // Same moment in time, but seen through lens of Paris wall-clock time. 

Count from era

I highly recommend that you do not process date and time values ​​as a reference from an era, for example, milliseconds since the beginning of 1970 UTC. But if necessary, create Instant from such a number.

 Instant instant = Instant.ofEpochMilli( 1_317_816_735_000L ); 

Then set the time zone as shown above if you want to move away from UTC.

 ZoneId z = ZoneId.of( "Pacific/Auckland" ); ZonedDateTime zdt = instant.atZone( z ); 

Your value is 1_317_816_735_000L :

  • 2011-10-05T12:12:15Z (Wednesday, October 05, 2011 12:12:15 GMT)
  • 2011-10-06T01:12:15+13:00[Pacific/Auckland] (Thursday, October 6, 2011 01:12:15 in Auckland, New Zealand).

Generate lines

To generate a string in the standard ISO 8601 format , simply call toString . Note that ZonedDateTime intelligently extends the standard format by adding the time zone name in square brackets.

 String output = zdt.toString(); 

For other formats, search for the DateTimeFormatter class. Already covered many times.

Specify FormatStyle and Locale .

 Locale l = new Locale( "en" , "NZ" ); DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM ).withLocale( l ); String output = zdt.format( f ); 

Note that the time zone has nothing to do with the locale. You can display the date / time in Europe/Paris in Japanese and the cultural norms, or the date in Asia/Kolkata in the Portuguese language and the cultural norms of Brazil.

About java.time

The java.time framework is built into Java 8 and later. These classes supersede the nasty old date and time classes, such as java.util.Date , .Calendar , and java.text.SimpleDateFormat .

The Joda-Time project, currently in maintenance mode , recommends switching to java.time.

To learn more, see the Oracle Tutorial . And a search for many examples and explanations.

Most of the functionality of java.time has been ported to Java 6 and 7 in ThreeTen-Backport and additionally adapted for Android in ThreeTenABP (see How to use ... ).

The ThreeTen-Extra project extends java.time with additional classes. This project is a testing ground for possible future additions to java.time. Here you can find some useful classes such as Interval , YearWeek , YearQuarter and others.

+15
Sep 02 '16 at 20:44
source share

The solution is actually quite simple (pure, simple Java):

 System.out.println(" NZ Local Time: 2011-10-06 03:35:05"); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime localNZ = LocalDateTime.parse("2011-10-06 03:35:05",formatter); ZonedDateTime zonedNZ = ZonedDateTime.of(localNZ,ZoneId.of("+13:00")); LocalDateTime localUTC = zonedNZ.withZoneSameInstant(ZoneId.of("UTC")).toLocalDateTime(); System.out.println("UTC Local Time: "+localUTC.format(formatter)); 

EXIT:

  NZ Local Time: 2011-10-06 03:35:05 UTC Local Time: 2011-10-05 14:35:05 
+7
Mar 09 '15 at 15:24
source share

I looked, and I don’t think this is the time zone in Java, which is GMT + 13. Therefore, I think you should use:

 Calendar calendar = Calendar.getInstance(); //OR Calendar.getInstance(TimeZone.getTimeZone("GMT")); calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY)+13); Date d = calendar.getTime(); 

(If after that “GMT” changes to this time zone and delete the second line of code)

OR

 SimpleDateFormat df = new SimpleDateFormat(); df.setTimeZone(TimeZone.getTimeZone("GMT+13")); System.out.println(df.format(c.getTime())); 

If you want to set a specific time / date, you can also use:

  calendar.set(Calendar.DATE, 15); calendar.set(Calendar.MONTH, 3); calendar.set(Calendar.YEAR, 2011); calendar.set(Calendar.HOUR_OF_DAY, 13); calendar.set(Calendar.MINUTE, 45); calendar.set(Calendar.SECOND, 00); 
+5
Oct 06 2018-11-11T00:
source share

Joda time

The java.util.Date/Calendar classes are a mess and should be avoided.

Update: The Joda-Time project is in maintenance mode. The team advises switching to the java.time classes.

Here is your answer using the Joda-Time 2.3 library. Very easy.

As indicated in the code example, I suggest you use the named time zones where possible, so that your programming can handle Daylight Saving Time (DST) and other anomalies.

If you placed T in the middle of the line instead of a space, you can skip the first two lines of code, dealing with formatting for parsing the line. The DateTime constructor can accept a string in the ISO 8601 format.

 // © 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.*; // Parse string as a date-time in UTC (no time zone offset). DateTimeFormatter formatter = org.joda.time.format.DateTimeFormat.forPattern( "yyyy-MM-dd' 'HH:mm:ss" ); DateTime dateTimeInUTC = formatter.withZoneUTC().parseDateTime( "2011-10-06 03:35:05" ); // Adjust for 13 hour offset from UTC/GMT. DateTimeZone offsetThirteen = DateTimeZone.forOffsetHours( 13 ); DateTime thirteenDateTime = dateTimeInUTC.toDateTime( offsetThirteen ); // Hard-coded offsets should be avoided. Better to use a desired time zone for handling Daylight Saving Time (DST) and other anomalies. // Time Zone list… http://joda-time.sourceforge.net/timezones.html DateTimeZone timeZoneTongatapu = DateTimeZone.forID( "Pacific/Tongatapu" ); DateTime tongatapuDateTime = dateTimeInUTC.toDateTime( timeZoneTongatapu ); 

Reset these values ​​...

 System.out.println( "dateTimeInUTC: " + dateTimeInUTC ); System.out.println( "thirteenDateTime: " + thirteenDateTime ); System.out.println( "tongatapuDateTime: " + tongatapuDateTime ); 

At startup ...

 dateTimeInUTC: 2011-10-06T03:35:05.000Z thirteenDateTime: 2011-10-06T16:35:05.000+13:00 tongatapuDateTime: 2011-10-06T16:35:05.000+13:00 
+3
Dec 11 '13 at 22:09
source share

I tried this code

 try{ SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss Z"); Date datetime = new Date(); System.out.println("date "+sdf.format(datetime)); sdf.setTimeZone(TimeZone.getTimeZone("GMT")); System.out.println("GMT "+ sdf.format(datetime)); sdf.setTimeZone(TimeZone.getTimeZone("GMT+13")); System.out.println("GMT+13 "+ sdf.format(datetime)); sdf.setTimeZone(TimeZone.getTimeZone("UTC")); System.out.println("utc "+sdf.format(datetime)); Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("GMT")); DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z"); formatter.setTimeZone(TimeZone.getTimeZone("GMT+13")); String newZealandTime = formatter.format(calendar.getTime()); System.out.println("using calendar "+newZealandTime); }catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } 

and getting this result

 date 06-10-2011 10:40:05 +0530 GMT 06-10-2011 05:10:05 +0000 // here getting 5:10:05 GMT+13 06-10-2011 06:10:05 +1300 // here getting 6:10:05 utc 06-10-2011 05:10:05 +0000 using calendar 06 Oct 2011 18:10:05 GMT+13:00 
+2
Oct 06 '11 at 5:13
source share

We can handle this using the offset value.

  public static long convertDateTimeZone(long lngDate, String fromTimeZone, String toTimeZone){ TimeZone toTZ = TimeZone.getTimeZone(toTimeZone); Calendar toCal = Calendar.getInstance(toTZ); TimeZone fromTZ = TimeZone.getTimeZone(fromTimeZone); Calendar fromCal = Calendar.getInstance(fromTZ); fromCal.setTimeInMillis(lngDate); toCal.setTimeInMillis(fromCal.getTimeInMillis() + toTZ.getOffset(fromCal.getTimeInMillis()) - TimeZone.getDefault().getOffset(fromCal.getTimeInMillis())); return toCal.getTimeInMillis(); } 

Excerpt from the test code:

  System.out.println(new Date().getTime()) System.out.println(convertDateTimeZone(new Date().getTime(), TimeZone .getDefault().getID(), "EST")); 

Output: 1387353270742 1387335270742

+2
Dec 18 '13 at 7:58
source share

We can get the UTC / GMT timestamp from the indicated date.

 /** * Get the time stamp in GMT/UTC by passing the valid time (dd-MM-yyyy HH:mm:ss) */ public static long getGMTTimeStampFromDate(String datetime) { long timeStamp = 0; Date localTime = new Date(); String format = "dd-MM-yyyy HH:mm:ss"; SimpleDateFormat sdfLocalFormat = new SimpleDateFormat(format); sdfLocalFormat.setTimeZone(TimeZone.getDefault()); try { localTime = (Date) sdfLocalFormat.parse(datetime); Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.getDefault()); TimeZone tz = cal.getTimeZone(); cal.setTime(localTime); timeStamp = (localTime.getTime()/1000); Log.d("GMT TimeStamp: ", " Date TimegmtTime: " + datetime + ", GMT TimeStamp : " + localTime.getTime()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return timeStamp; } 

It will return UTC time based on the past date.

  • We can do the opposite, like a UTC time stamp, on the current date and time (vice versa)

      public static String getLocalTimeFromGMT(long gmtTimeStamp) { try{ Calendar calendar = Calendar.getInstance(); TimeZone tz = TimeZone.getDefault(); calendar.setTimeInMillis(gmtTimeStamp * 1000); // calendar.add(Calendar.MILLISECOND, tz.getOffset(calendar.getTimeInMillis())); SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); Date currenTimeZone = (Date) calendar.getTime(); return sdf.format(currenTimeZone); }catch (Exception e) { } return ""; } 

Hope this helps others. Thank!!

+1
Dec 05 '14 at 2:46
source share

Quick way:

 String dateText ="Thu, 02 Jul 2015 21:51:46"; long hours = -5; // time difference between places DateTimeFormatter formatter = DateTimeFormatter.ofPattern(E, dd MMM yyyy HH:mm:ss, Locale.ENGLISH); LocalDateTime date = LocalDateTime.parse(dateText, formatter); date = date.with(date.plusHours(hours)); System.out.println("NEW DATE: "+date); 

Exit

NEW DATE: 2015-07-02T16: 51: 46

+1
Jul 2 '15 at 22:52
source share
 public Timestamp convertLocalTimeToServerDatetime(String dt,String timezone){ String clientDnT = dt ;// "2017-06-01 07:20:00"; try{ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = sdf.parse(clientDnT); TimeZone tz = TimeZone.getTimeZone(timezone.trim()); // get time zone of user sdf.setTimeZone(tz); // Convert to servertime zone SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); TimeZone tzInAmerica = TimeZone.getDefault(); sdf1.setTimeZone(tzInAmerica); // assign date to date String serverDate = sdf1.format(date); // Convert to servertime zone to Timestamp Date date2 = sdf.parse(serverDate); Timestamp tsm = new Timestamp(date2.getTime()); return tsm; } catch(Exception e){ System.err.println(e); } return null; } 
+1
Jun 02 '17 at 7:27
source share

Find the duration or time interval with two different time zones

 import org.joda.time.{DateTime, Period, PeriodType} val s1 = "2019-06-13T05:50:00-07:00" val s2 = "2019-10-09T11:30:00+09:00" val period = new Period(DateTime.parse(s1), DateTime.parse(s2), PeriodType dayTime()) period.getDays period.getMinutes period.getHours 

exit period = P117DT13H40M

 days = 117 minutes = 40 hours = 13 
+1
Jun 21 '19 at 9:30
source share

I would like to give a modern answer.

You really do not have to convert the date and time from a string with one Greenwich offset to a string with a different GMT offset and in a different format. Rather, in your program, store the moment (point in time) as a proper date and time object. Only when you need to produce a string, format your object in the desired string.

java.time

Input parsing

  DateTimeFormatter formatter = new DateTimeFormatterBuilder() .append(DateTimeFormatter.ISO_LOCAL_DATE) .appendLiteral(' ') .append(DateTimeFormatter.ISO_LOCAL_TIME) .toFormatter(); String dateTimeString = "2011-10-06 03:35:05"; Instant instant = LocalDateTime.parse(dateTimeString, formatter) .atOffset(ZoneOffset.UTC) .toInstant(); 

For most purposes, Instant is a good choice for saving a point in time. If you need to clearly indicate that the date and time came from GMT, use OffsetDateTime instead.

Convert, format and print

  ZoneId desiredZone = ZoneId.of("Pacific/Auckland"); Locale desiredeLocale = Locale.forLanguageTag("en-NZ"); DateTimeFormatter desiredFormatter = DateTimeFormatter.ofPattern( "dd MMM uuuu HH:mm:ss OOOO", desiredeLocale); ZonedDateTime desiredDateTime = instant.atZone(desiredZone); String result = desiredDateTime.format(desiredFormatter); System.out.println(result); 

This is printed:

06 Oct 2011 16:35:05 GMT + 13: 00

I indicated the Pacific / Auckland time zone, not the offset that you mentioned, at 13:00. I understood that you wanted New Zealand time, and Pacific / Auckland would tell the reader better. The time zone also takes into account daylight saving time (DST), so you do not need to take this into account in your own code (for most purposes).

Since Oct written in English, it is a good idea to give the formatter an explicit language standard. GMT can also be localized, but I think it just prints GMT in all locales.

OOOO in the format string format string is one way to print the offset, which might be a better idea than printing the time zone abbreviation you would get from z , since time zone abbreviations are often ambiguous. If you want NZDT (for New Zealand Daylight NZDT Time), just put z instead.

Your questions

I will answer your numbered questions regarding modern classes in java.time.

Maybe:

  1. Set time at the facility

No, modern classes are immutable. You need to create an object from the very beginning with the desired date and time (this has a number of advantages, including thread safety).

  1. (Possible) Set the time zone of the initial time stamp

The atZone method that I use in the code returns a ZonedDateTime with the specified time zone. Other date and time classes have a similar method, sometimes called atZoneSameInstant or other names.

  1. Format the timestamp using the new timezone

With java.time, converting to a new time zone and formatting are two separate steps, as shown.

  1. Return a string with a new time zone.

Yes, convert to the desired time zone as shown, and format as shown.

I found that every time I try to set the time as follows:

 calendar.setTime(new Date(1317816735000L)); 

The local TimeZone machine is used. Why is this so?

This is not what you think, and it’s good if you show only a couple (many) design problems with old classes.

  • Date does not have a time zone. Only when you print it, its toString method captures your local time zone and uses it to render the string. This is also true for new Date() . This behavior has confused many programmers over the past 25 years.
  • Calender has a time zone. It does not change when you do calendar.setTime(new Date(1317816735000L)); .

Link

Oracle Tutorial: Date Time explaining how to use java.time.

+1
Jul 15 '19 at 8:43
source share

display date and time for all time zones

 import java.util.Calendar; import java.util.TimeZone; import java.text.DateFormat; import java.text.SimpleDateFormat; static final String ISO8601 = "yyyy-MM-dd'T'HH:mm:ssZ"; DateFormat dateFormat = new SimpleDateFormat(ISO8601); Calendar c = Calendar.getInstance(); String formattedTime; for (String availableID : TimeZone.getAvailableIDs()) { dateFormat.setTimeZone(TimeZone.getTimeZone(availableID)); formattedTime = dateFormat.format(c.getTime()); System.out.println(formattedTime + " " + availableID); } 
+1
Jul 30 '19 at 9:55
source share

Your approach works without any changes.

 Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT")); // Timestamp for 2011-10-06 03:35:05 GMT calendar.setTime(new Date(1317872105000L)); DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); formatter.setTimeZone(TimeZone.getTimeZone("GMT+13")); // Prints 2011-10-06 16:35:05 GMT+13:00 System.out.println(formatter.format(calendar.getTime())); 
0
Apr 16 '16 at 9:35
source share

A few simple ways. It is important to remember that the date does not support the time zone, its only long millis number, as it is interpreted here.

 /** * Converts source in GMT+0 to timezone specified by server * * @throws IllegalStateException if server timezone wasnt set */ public static Date convertGmt(Date source) { if (timeZoneServer == null) { throw new IllegalStateException("Server timezone wasnt set"); } long rawOffset = timeZoneServer.getRawOffset(); Date dest = new Date(source.getTime() + rawOffset); return dest; } /** * Converts source in device timezone format to GMT */ public static Date convertToGmt(Date source) { int rawOffset = TimeZone.getDefault().getRawOffset(); Date dest = new Date(source.getTime() - rawOffset); return dest; } 

TimezoneServer is something like TimeZone timeZoneServer = TimeZone.getTimeZone("GMT+1")

-one
Dec 11 '13 at 6:58
source share



All Articles