11

I need to send data in json. What's important is that I want the locale to be preserved so that the receiver gets the date in his local time. How can I do that?

I cannot simply use Date.toString() because then I won't be able to parse it back to date on the receiving end if their locale is different(different day and month names and so on).

Is there a solution to this?

Puneet Pandey
  • 960
  • 2
  • 14
  • 28
Greyshack
  • 1,901
  • 7
  • 29
  • 48

7 Answers7

6

A ms long time since 1970 is fine, but not human readable, and hence a PITA for testing/developing.

Hence use the ISO 8601 standard date time "yyyy-MM-dd'T'HH:mm:ss" (where 'T' is just a literal T (one often sees a space here; and fractional seconds .SSS).

Time zone is possible too, but hopefully not needed (= incorporated in the localized time).

Before java 8 using SimpleDateFormat.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
5

tl;dr

Instant.now()
       .toString()

2017-01-23T12:34:56.123456789Z

UTC

Generally best to exchange data for date-time values in UTC (GMT). Let the receiver adjust into a desired time zone.

Instant

The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds.

Instant instant = Instant.now() ;
String output = instant.toString() ;  // Generate a String in standard ISO 8601 format.

2017-01-23T12:34:56.123456789Z

You can easily parse that string.

Instant instant = Instant.parse( "2017-01-23T12:34:56.123456789Z" ) ; 

ISO 8601

The ISO 8601 standard defines clear easy-to-read easy-to-parse formats for textual representations of date-time values. These formats are ideal for data-exchange.

For a moment in UTC, that means the format seen in example above. The T separates the date portion from the time of day portion. The Z on the end is short for Zulu and means UTC.

Locale

The Question mentions locale as if related to time zone. A Locale has nothing to do with time zone. A Locale specifies (a) the human language for translation of name of day, name of month, and such, and (b) the cultural norms deciding issues of abbreviation, capitalization, punctuation, and such.

A time zone is a history of changes to a region’s offset-from-UTC, tracking anomalies causing those changes such as Daylight Saving Time (DST).

Search Stack Overflow to learn more. This has already been covered many hundreds of times already. Search for classes such as ZoneId, ZoneOffset, ZonedDateTime, Instant, OffsetDateTime, and DateTimeFormatter. Read the Oracle Tutorial on the java.time classes.

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

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
3

Use java.util.Date's getTime method for the timestamp. Once you convert it back to a date every receiver can display it using it's local time zone.

Remember that Date

represents a specific instant in time, with millisecond precision.

The toString method just formats it in a specific way:

dow mon dd hh:mm:ss zzz yyyy

Chosing to send the timestamp means you also use less bandwidth.

Laurentiu L.
  • 6,566
  • 1
  • 34
  • 60
  • what happens when the Date created in one time-zone and passed to and consumed in another time-zone? – aviad Aug 03 '15 at 10:04
  • 1
    Date created in a timezone is converted to the number of milliseconds since January 1, 1970, 00:00:00 GMT (via getTime) and then this number gets converted to a date whatever timezone. – Laurentiu L. Aug 03 '15 at 10:06
  • It's probably what I'm looking for. How long is the number of milliseconds? – Greyshack Aug 03 '15 at 10:09
  • @Greyshack it's long :) As in the java primitive data type named 'long'. Current millis is 1438596711244. It will stay 14 characters in miliseconds for quite a while. – Laurentiu L. Aug 03 '15 at 10:12
2

The proper way to do this is to write your date in ISO 8601 format: i.e. 2015-08-03T4:50:49+00:00

Not only will in include the timezone but also any standard decoder on the receiving end of your JSON will be able to decode it without problems.

For the sending part, if you are writing the string yourself, well just format it:

ZonedDateTime.now( ZoneId.systemDefault() )
             .format( DateTimeFormatter.ISO_DATE_TIME )

But if you are using any JSON serializers to transform from your Java objects (like Jackson for example), then just make the object attribute a java.util.Date and the serializer should know what to do, given the right setup. See this answer for Jackson, or this one for Jersey. They both use Joda Time.

Community
  • 1
  • 1
mprivat
  • 21,582
  • 4
  • 54
  • 64
1

I think there is the simple way to do this,

DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
yourJsonObject.accumulate("yourDateVarible",dateFormat.format(new Date()));
SwapnilKumbhar
  • 347
  • 2
  • 5
  • 17
0

There are many ways to do that. One way to convert date in milliseconds which does not depend on locale and use it further. Another way to change date in utc format and use it further.If your server's time zone set to UTC java.util.Date will work perfectly because it takes systems time zone by default while using new Date("some date").Example :

   long lastAccessedDate =  110002028250;
  String myDate = new java.util.Date(lastAccessedDate()).toString();

myDate will be "Tue Jun 06 05:30:00 UTC 2017", if system time zone is UTC.

abhishek ringsia
  • 1,970
  • 2
  • 20
  • 28
  • I must disagree with all your points. A count of milliseconds is ambiguous as to both the [epoch reference date](https://en.wikipedia.org/wiki/Epoch_(reference_date)#Notable_epoch_dates_in_computing) and the granularity (days, whole seconds, milliseconds, microseconds, nanos). There is no such thing as 'utc format'. The default time zone of host OS or the JVM is outside the control of the programmer and therefore unreliable; better to explicitly specify your expected/desired time zone. The troublesome `Date` class uses a terrible format, and is now legacy, supplanted by `java.time.Instant`. – Basil Bourque Oct 31 '17 at 16:43
-1

Try this format : 2017-03-20T00:00:00.000+0100

fjgarzon
  • 44
  • 4