Timestamp conversion from one timezone - java

I need to convert the timestamp from one timezone to another time zone and retrieve the time in milliseconds for that timezone.
I tried doing that below, but its not working out.
SimpleDateFormat localDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
localDateFormat.setTimeZone(TimeZone.getTimeZone("anothertimezone));
//Current Date Time in Local Timezone
System.out.println("Current Date and Time in local timezone: " + localDateFormat.format( new Date()));
Calendar calendar = localDateFormat.getCalendar();
System.out.println(calendar.getTime());
The calendar.gettime is printing the current machine's time and not the time based on the timezone.

Not quite sure what you are trying to achieve, but this prints the current time in CEST and IST:
SimpleDateFormat localDateFormat =
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
System.out.println("Current Date/Time in local timezone: " +
localDateFormat.format( new Date()));
localDateFormat.setTimeZone(TimeZone.getTimeZone("IST"));
System.out.println("Current Date/Time in IST timezone: " +
localDateFormat.format( new Date()));
You can also take a date and time in string form and parse it:
// create a string showing date and time in IST time zone
String istDateString = localDateFormat.format( new Date());
Date istDate = localDateFormat.parse( istDateString, new ParsePosition(0) );
System.out.println( istDateString + " parsed to " + istDate );
The default used in Date.toString is, of course, the local setting.

Adjusting time zones leaves you with the same milliseconds since epoch.
Using Joda-Time 2.3 is much easier than the notoriously troublesome java.util.Date and .Calendar classes bundled with Java. While a java.util.Date has no time zone, a DateTime object in Joda-Time does indeed know its own assigned time zone.
Here is some example code. All of these DateTime objects represent the same moment in the timeline of the Universe, that is, the same number of milliseconds since the Unix epoch (the beginning of 1970). To verify, call the getMillis method to extract the number of milliseconds.
String inputRaw = "2014-01-02 03:04:05";
String input = inputRaw.replace( " ", "T" ); // Convert to strict version of ISO 8601 standard format.
DateTimeZone timeZoneParis = DateTimeZone.forID( "Europe/Paris" );
DateTime dateTimeParis = new DateTime( input, timeZoneParis ); // Interpret that string as being in a particular time zone.
DateTime dateTimeUtc = dateTimeParis.withZone( DateTimeZone.UTC );
DateTime dateTimeMontréal = dateTimeParis.withZone( DateTimeZone.forID( "America/Montreal" ) );
Dump to console…
System.out.println( "input: " + input );
System.out.println( "dateTimeParis: " + dateTimeParis );
System.out.println( "dateTimeParis millis: " + dateTimeParis.getMillis() );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "dateTimeUtc millis: " + dateTimeUtc.getMillis() );
System.out.println( "dateTimeMontréal: " + dateTimeMontréal );
System.out.println( "dateTimeMontréal millis: " + dateTimeMontréal.getMillis() );
When run…
input: 2014-01-02T03:04:05
dateTimeParis: 2014-01-02T03:04:05.000+01:00
dateTimeParis millis: 1388628245000
dateTimeUtc: 2014-01-02T02:04:05.000Z
dateTimeUtc millis: 1388628245000
dateTimeMontréal: 2014-01-01T21:04:05.000-05:00
dateTimeMontréal millis: 1388628245000

Related

What is the Time format for this "date": "2014-08-20 00:00:00 -0500"?

I tried converting this date the following way:
SimpleDateFormat fromFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSSZ");
but I got:
java.text.ParseException: Unparseable date: "2014-09-20 00:00:00 -0500" (at offset 20)
That "-0500" is the offset from UTC, in RFC822 format. You just want Z, without the SSS.
The Android SimpleDateFormat docs have it like this in the table:
Symbol: Z
Meaning: time zone (RFC 822)
Kind: (Time Zone)
Example: Z/ZZ/ZZZ:-0800 ZZZZ:GMT-08:00 ZZZZZ:-08:00
I would also personally specify a locale, as a matter of course: this is a machine-readable format rather than a human-oriented format, so I'd usually specify Locale.US:
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z",
Locale.US);
String text = "2014-08-20 00:00:00 -0500";
System.out.println(format.parse(text));
The answer by Jon Skeet is correct.
Standard Date-Time Format
Here is some example code showing how to transform your string into compliance with ISO 8601.
String inputRaw = "2014-08-20 00:00:00 -0500";
String input = inputRaw.replaceFirst( " ", "T" ).replaceFirst( " ", "" ); // Replace first SPACE with a 'T', and delete second SPACE.
// input is "2014-08-20T00:00:00-0500".
Joda-Time
You can pass that compliant string directly to the constructor of DateTime in Joda-Time. Ditto for the equivalent in the java.time package in Java 8 (inspired by Joda-Time).
DateTimeZone timeZone = DateTimeZone.forID( "America/Montreal" ); // Specify it rather than have JVM's default applied.
DateTime dateTimeMontréal = new DateTime( input, timeZone );
DateTime dateTimeUtc = dateTimeMontréal.withZone( DateTimeZone.UTC );
Dump to console.
System.out.println( "inputRaw: " + inputRaw );
System.out.println( "input: " + input );
System.out.println( "dateTimeMontréal: " + dateTimeMontréal );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
When run…
inputRaw: 2014-08-20 00:00:00 -0500
input: 2014-08-20T00:00:00-0500
dateTimeMontréal: 2014-08-20T01:00:00.000-04:00
dateTimeUtc: 2014-08-20T05:00:00.000Z

Simpledateformat is not parsing milliseconds

String dateTimePattern = "yyyy-MM-dd HH:mm:ss.SSS";
SimpleDateFormat sdf = new SimpleDateFormat(dateTimePattern);
Date startTime = sdf.parse("2014-03-14 04:16:58.666");
System.out.println(startTime);
Output
Fri Mar 14 04:16:58 CDT 2014
Why is not printing milliseconds?
The problem here is not that the milliseconds are not getting parsed, your startTime includes the milliseconds you have provided. The problem is that they are not getting printed.
You need to format your output if you want something other than the default format from Date#toString():
Converts this Date object to a String of the form:
dow mon dd hh:mm:ss zzz yyyy
You can use your SimpleDateFormat to format your output too, which will give you milliseconds:
System.out.println(sdf.format(startTime));
You are printing startTime directly (e.g. the toString() from java.util.Date); if you want your output to match your specified DateFormat you could do -
String dateTimePattern = "yyyy-MM-dd HH:mm:ss.SSS";
SimpleDateFormat sdf = new SimpleDateFormat(dateTimePattern);
Date startTime = sdf.parse("2014-03-14 04:16:58.666");
System.out.println(sdf.format(startTime)); // <-- use the DateFormat.
Which will output
2014-03-14 04:16:58.666
The other answers are correct.
Avoid j.u.Date
You would have simpler code and none of that confusion if you used Joda-Time (or java.time package in Java 8) rather than the notoriously troublesome java.util.Date & .Calendar & java.text.SimpleDateFormat classes bundled with Java.
Joda-Time
Joda-Time has built-in automatic parsers for ISO 8601 formats. Your format would work if you replaced that space with a T.
Example code using Joda-Time 2.3…
String inputRaw = ( "2014-03-14 04:16:58.666" );
String input = inputRaw.replace( " ", "T" );
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTime dateTime = new DateTime( input, timeZone );
DateTime dateTimeUtc = dateTime.withZone( DateTimeZone.UTC );
Dump to console…
System.out.println( "input: " + input );
System.out.println( "dateTime: " + dateTime );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
When run…
input: 2014-03-14T04:16:58.666
dateTime: 2014-03-14T04:16:58.666+01:00
dateTimeUtc: 2014-03-14T03:16:58.666Z

Check if time in millis is tomorrow

I want to query SQLite table and get records where the time field (which is a String representing long time in millis) is in the range of tomorrow from querying time.
I also have a field which holds the record date time like this:
dd/MM/yyyy, HH:mm:ss
How would you recommend implementing this?
As per your comment you are open to modify the schema for better performance. So it is better to save time as long (unix timestamp) in database and having an index on that. Once that is done you can simply get tomorrows date at 00:00 in local time zone and convert it to unix timestamp and query based on that. Here is how you can get tomorrows timestamp at 00:00,
public static long getTimeStampAt0000(long timestamp) {
Calendar givenDate = Calendar.getInstance();
givenDate.setTimeInMillis(timestamp);
givenDate.set(Calendar.HOUR_OF_DAY, 0);
givenDate.set(Calendar.MINUTE, 0);
givenDate.set(Calendar.SECOND, 0);
givenDate.set(Calendar.MILLISECOND, 0);
return givenDate.getTimeInMillis();
}
public static long getTimeStampAt0000ForTomorrow() {
long now = System.currentTimeMillis();
long nowAt0000 = getTimeStampAt0000(now);
if (now == nowAt0000) {
// if being queried at 00:00, we are assuming we want same or else we can just remove
// this condition
return nowAt0000;
} else {
return nowAt0000 + 86400000;
}
}
The SQLite doc says that it stores as:
INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.
Are you certain you have milliseconds since epoch or seconds?
The bundled java.util.Date and Calendar classes are notoriously troublesome. Avoid them. Use either Joda-Time or the new java.time.* package in Java 8.
Note that both java.util.Date and Joda-Time DateTime use milliseconds since epoch, while the new java.time uses nanoseconds. Multiply by 1000L as needed.
When talking about "today" and "tomorrow" with a date-time, you must specify a time zone. The beginning and ending of a day depends on time zone.
// Simulate input.
long millis = DateTime.now().getMillis();
// Use a proper time zone name rather than 3-letter codes.
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" ); // Formerly known as Calcutta, India.
DateTime dateTime = new DateTime( millis, timeZone );
DateTime aDayLater = dateTime.plusDays( 1 );
// "Tomorrow" is a span of time.
DateTime startOfToday = new DateTime( timeZone ).withTimeAtStartOfDay();
// Interval comparison is done in "half-open" approach where beginning is inclusive and ending is exclusive.
Interval tomorrow = new Interval( startOfToday.plusDays( 1 ), startOfToday.plusDays( 2 ) );
boolean isDateTimeOccurringTomorrow = tomorrow.contains( dateTime );
boolean isADayLaterOccurringTomorrow = tomorrow.contains( aDayLater );
Dump to console…
System.out.println( "millis: " + millis );
System.out.println( "dateTime: " + dateTime );
System.out.println( "aDayLater: " + aDayLater );
System.out.println( "startOfToday: " + startOfToday );
System.out.println( "tomorrow: " + tomorrow );
System.out.println( "isDateTimeOccurringTomorrow: " + isDateTimeOccurringTomorrow );
System.out.println( "isADayLaterOccurringTomorrow: " + isADayLaterOccurringTomorrow );
When run…
millis: 1392883763016
dateTime: 2014-02-20T13:39:23.016+05:30
aDayLater: 2014-02-21T13:39:23.016+05:30
startOfToday: 2014-02-20T00:00:00.000+05:30
tomorrow: 2014-02-21T00:00:00.000+05:30/2014-02-22T00:00:00.000+05:30
isDateTimeOccurringTomorrow: false
isADayLaterOccurringTomorrow: true

Unparseable date: "2014-02-24T00:54:12.417-06:00" in java

I want to convert date: 2014-02-24T00:54:12.417-06:00 into IST format.
Till far I did:
String s = "2014-02-24T00:54:12.417-06:00";
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZZZ");
Date d = formatter.parse(s);
TimeZone tx=TimeZone.getTimeZone("Asia/Calcutta");
formatter.setTimeZone(tx);
System.out.println("Formatted date in IST = " + formatter.format(d));
String istDateFormat = formatter.format(d);
//Date da=formatter.format(d);
return istDateFormat;
But I am getting error:
Unparseable date: "2014-02-24T00:54:12.417-06:00"
DateFormat formatter = new SimpleDateFormat(""yyyy-MM-dd'T'HH:mm:ss.SSSXXX"");
This is shold work, check the example in the Java Doc. There is : in between your TimeZone,
Your pattern suitable for 2001-07-04T12:08:56.235-0700 format.
The java.util.Date & .Calendar & SimpleDateFormat classes bundled with Java are notoriously troublesome. Avoid them.
The alternatives, Joda-Time and Java 8’s new java.time package solve your problem with less code. No need to bother with formatters and parsing as they both take ISO 8601 formatted strings directly.
Note one big difference: While java.util.Date objects have no time zone (effectively UTC/GMT), in both Joda-Time (DateTime) and java.time (ZonedDateTime) the date-time object knows its own assigned time zone and offset.
Joda-Time
String input = "2014-02-24T00:54:12.417-06:00";
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeIndia = new DateTime( input, timeZone ); // Parse as a -06:00 value, then adjust 11.5 hours to India +05:30 time zone.
DateTime dateTimeUtc = dateTimeIndia.withZone( DateTimeZone.UTC ); // For comparison.
Dump to console…
System.out.println( "input: " + input );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "dateTimeIndia: " + dateTimeIndia );
When run…
input: 2014-02-24T00:54:12.417-06:00
dateTimeUtc: 2014-02-24T06:54:12.417Z
dateTimeIndia: 2014-02-24T12:24:12.417+05:30
java.time (Java 8)
String input = "2014-02-24T00:54:12.417-06:00";
ZoneId zoneId = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zonedDateTimeIndia = ZonedDateTime.parse( input ).withZoneSameInstant( zoneId ); // Parse as a -06:00 value, then adjust 11.5 hours to India +05:30 time zone.
ZonedDateTime zonedDateTimeUtc = zonedDateTimeIndia.withZoneSameInstant( ZoneOffset.UTC ); // For comparison.
Dump to console…
System.out.println( "input: " + input );
System.out.println( "zonedDateTimeUtc: " + zonedDateTimeUtc );
System.out.println( "zonedDateTimeIndia: " + zonedDateTimeIndia );
When run…
input: 2014-02-24T00:54:12.417-06:00
zonedDateTimeUtc: 2014-02-24T06:54:12.417Z
zonedDateTimeIndia: 2014-02-24T12:24:12.417+05:30[Asia/Kolkata]
Use this format: "yyyy-MM-dd'T'HH:mm:ss.SSSX"
You are using RFC time zone notation for your date format.
But your date string is ISO formatted
So it not able to parse your date.
Either do one of the following
change the formatter to have ISO format (i.e change ZZZ to XXX)
Or change you date string like 2014-02-24T00:54:12.417 -0600

Convert Epoch time to date and Date to Epoch time in Android [duplicate]

This question already has answers here:
Java 8 Date and Time: parse ISO 8601 string without colon in offset [duplicate]
(4 answers)
Closed 3 years ago.
StrDate = "2011-07-19T18:23:20+0000";
How can I get an epoch time for the above date format in android
also I would like to know how to convert a epoch time to the above date format.
I would appreciate a direct answer with an example.
Example code using Joda-Time 2.3.
Unix time is number of seconds since beginning of 1970 in UTC/GMT.
How can I get an epoch time for the above date format in android
DateTime dateTimeInUtc = new DateTime( "2011-07-19T18:23:20+0000", DateTimeZone.UTC );
long secondsSinceUnixEpoch = ( dateTimeInUtc.getMillis() / 1000 ); // Convert milliseconds to seconds.
…and…
how to convert a epoch time to the above date format.
String dateTimeAsString = new DateTime( secondsSinceUnixEpoch * 1000, DateTimeZone.UTC ).toString();
To dump those values to the console…
System.out.println( "dateTimeInUtc: " + dateTimeInUtc );
System.out.println( "secondsSinceUnixEpoch: " + secondsSinceUnixEpoch );
System.out.println( "dateTimeAsString: " + dateTimeAsString );
Bonus: Adjust to another time zone.
DateTime dateTimeMontréal = dateTimeInUtc.withZone( DateTimeZone.forID( "America/Montreal" ) );
You should use SimpleDateFormat. That class both supports formatting, and parsing.
Sample code:
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZZZZ");
Date gmt = formatter.parse("2011-07-19T18:23:20+0000");
long millisecondsSinceEpoch0 = gmt.getTime();
String asString = formatter.format(gmt);
Note that a Date instance in Java, always represent milliseconds since epoch 0, in UTC/GMT, but it is printed in local time when you print it.
To answer your question a bit late but Joda-Time will be able to handle both in a simply and clean way.
Using Joda-Time
1.Epoch time to Date
Where date is your epoch time
DateTime dateTime = new DateTime(date*1000L);
System.out.println("Datetime ..." + dateTime);
Datetime from Epoch ...2014-08-01T13:00:00.000-04:00
2.Date to epoch
DateTime fromDate = new DateTime("2011-07-19T18:23:20+0000");
long epochTime = fromDate.getMillis();
System.out.println("Date is.." + fromDate + " epoch of date " + epochTime);
Date is..2011-07-19T14:23:20.000-04:00 epoch of date 1311099800000

Categories