I receive datetime strings with no timezone qualifier in the format:
2014-01-30 07:48:25
I know that the strings are produced by a server in Florida. Is there a way using java.util or joda Date libs to specify that the date is from Florida then parse it with the appripriate UTC offset, depending on where it falls in the calendar for daylight savings time?
Assuming you are referring to the part of Florida following EST, you can set the timezone for SimpleDateFormat and set your TimeZone to EST.
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
format.setTimeZone(TimeZone.getTimeZone("America/New_York"));
Date date = format.parse("2014-01-30 07:48:25");
Your parsed date now can be utilized by your default TimeZone of the system (or set it to your liking as we did in the first place).
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
System.out.println(date);
The output I get for your date offset to UTC:
Thu Jan 30 12:48:25 UTC 2014
You can provide a "source timezone" to an instance of SimpleDateFormat and the to-be-parsed date string is then converted to your local/default timezone.
TimeZone timeZone = TimeZone.getTimeZone("America/New_York")
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
sdf.setTimeZone(getTimeZone(source));
Be careful when providing the time zone name. TimeZone will silently fail over to GMT if you pass in a string it does not understand as a timezone.
Just to complete previous answers. The same funcionality with Joda-Time:
DateTime dateTime = DateTime.parse("2014-01-30 07:48:25", DateTimeFormat
.forPattern("yyyy-MM-dd HH:mm:ss")
.withZone(DateTimeZone.forID("America/New_York")));
System.out.println(dateTime);
System.out.println(dateTime.withZone(DateTimeZone.UTC));
System.out.println(dateTime.withZone(DateTimeZone.forID("Europe/Madrid")));
---
2014-01-30T07:48:25.000-05:00
2014-01-30T12:48:25.000Z
2014-01-30T13:48:25.000+01:00
Related
I try to convert String to Date format but I got an exception!
Here is my code:
SimpleDateFormat format = new SimpleDateFormat("dd-MMM-yyyy");
startDate = format.parse(startDateString);
it should convert "14-MAY-2004" to Date. Thanks.
java.time
I recommend that you use java.time, the modern Java date and time API, for your date work.
DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("d-MMM-uuuu")
.toFormatter(Locale.ENGLISH);
String startDateString = "14-MAY-2004";
LocalDate startDate = LocalDate.parse(startDateString, dateFormatter);
System.out.println(startDate);
Output is:
2004-05-14
Only if you indispensably need a Date object for a legacy API not yet upgraded to java.time, convert:
Instant startOfDay = startDate.atStartOfDay(ZoneId.systemDefault()).toInstant();
Date oldfashionedDate = Date.from(startOfDay);
System.out.println(oldfashionedDate);
Output in my time zone:
Fri May 14 00:00:00 CEST 2004
What went wrong in your code?
It’s almost certainly a locale problem. You didn’t specify a locale and hence no language for the month name or abbreviation. Always do that when the date string includes text in some language. Your SimpleDateFormat was using the default formatting locale of your JVM, and if that was a non-English-speaking locale, parsing was deemed to fail with an exception as you mentioned.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Similar question: Java - Unparseable date
From the statment "it should convert 14-MAY-2004 to date" i assume your input string is 14-MAY-2004 and you want this string to be converted to Date
String js="14-May-2004";
Date dt=new Date(js);
LocalDateTime localDateTime=dt.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
localDateTime.format(DateTimeFormatter.ofPattern("dd-MM-yyyy"));//or in the same format use- "dd-MMM-yyyy"
I have read a bunch of posts on this, but, I am obviously missing something. I have date string, and a time zone. I am trying to instantiate a date object as follows:
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
java.util.Date dateObj = sdf.parse("2013-10-06 13:30:00");
System.out.println(dateObj);
What is printed is:
Sun Oct 06 09:30:00 EDT 2013
What I want is a date object in UTC format. Not one converted to EDT. What am I doing wrong?
Thanks.
This is because a Date object does not store any timezone information. Date basically only stores the number of milliseconds since the epoch (Jan. 1, 1970). By default Date will use the timezone associated with the JVM. In order to preserve timezone information you should continue using the DateFormat object that you've already got.
See DateFormat#format(Date): http://docs.oracle.com/javase/7/docs/api/java/text/DateFormat.html#format(java.util.Date)
The following should give you what you're looking for:
System.out.println(sdf.format(dateObj));
Try below code, you'll see that the date parsed 1st time is different from the one parsed after setting timezone. Actually the date is parsed as expected in right timezone. It s while printing it gives you get the machines's default TZ.
You could have printed the dateObj.toGMTString() to check the same, but that is deprecated.
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date dateObj = sdf.parse("2013-10-06 13:30:00");
System.out.println(dateObj.toString());
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
dateObj = sdf.parse("2013-10-06 13:30:00");
System.out.println(dateObj.toString());
I am getting a date/time string from web in the format of yyyy-mm-dd HH:MM:SS and it is in UTC.
I have to create a Date object and print the date object in GMT format, but I don't want the to change, for example if I read the date as 2014-10-22 09:00:00, then it should be displayed as 2014-10-22 09:00:00 GMT instead of 2014-10-22 13:30:00
How do I do this? Please suggest me.
(FYI, Currently, UTC time is 10:25 AM, in india current time is 3:55 PM).
I am using Jaxb parser to parse the XML. Any suggestions are invited
You could use a SimpleDateFormat to parse the date, and then reformat it to a different timezone.
String toTimeZone = "GMT";
String fromTimeZone = "UTC";
String stingvalue = "2014-10-14 03:05:39";
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone(fromTimeZone));
Date parsedDate = dateFormat.parse(stingvalue);
dateFormat.setTimeZone(TimeZone.getTimeZone(toTimeZone));
String newDate = dateFormat.format(parsedDate);
Explanation
The Java Date class counts time in milliseconds from January 1, 1970 00:00:00.000 GMT. As such, your Dates are time zone neutral. To get date in a different time zone, simply format it differently
I have done this for my Calendar instance to return Date in UTC timezone:
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:SS Z");
TimeZone tz = TimeZoneUtil.getTimeZone(StringPool.UTC);
formatter.setTimeZone(tz);
Date dtStart = null;
Date dtEnd = null;
try{
dtStart = formatter.parse(formatter.format(startDate.getTime()));
dtEnd = formatter.parse(formatter.format(endDate.getTime()));
}catch (Exception e) {
e.getStackTrace();
}
It works fine till I format calendar timestamp to return a string date with required timezone but when I parse that string date to Date date, it again picks up local timezone?
I need to store Date object in UTC timezone.
Any help will be highly appreciated!
You can use this:
Date localTime = new Date();
//creating DateFormat for converting time from local timezone to GMT
DateFormat converter = new SimpleDateFormat("dd/MM/yyyy:HH:mm:ss");
//getting GMT timezone, you can get any timezone e.g. UTC
converter.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("local time : " + localTime);;
System.out.println("time in GMT : " + converter.format(localTime));
It will give:
local time: Fri Jun 21 11:55:00 UTC 2013
time in GMT : 21/06/2013:11:55:00
I hope it will help.
Cheers.
Date object in java will always store the values in the host machine (your system) time zone information.
This is from javadoc :
Although the Date class is intended to reflect coordinated universal time (UTC), it may not do so exactly, depending on the host environment of the Java Virtual Machine.
You should trying using Joda Time which is much advanced.
Instead of setting TimeZone in multiple places, it is a good idea to set timezone using -Duser.timezone=GMT or PST.
And, you can easily test how Java deals with timezone and getTime() ignores timezone with an actual example:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); // print with timezone
TimeZone timeZone = TimeZone.getTimeZone(ZoneId.of("GMT"));
TimeZone.setDefault(timeZone); // set system timezone as GMT
sdf.setTimeZone(timeZone); // formatter also has a timezone
Date date = new Date();
System.out.println(date); // system says GMT date
System.out.println(date.getTime()); // only prints time in milliseconds after January 1, 1970 00:00:00 GMT
System.out.println(sdf.format(date));
timeZone = TimeZone.getTimeZone(ZoneId.of("America/Los_Angeles"));
TimeZone.setDefault(timeZone); // set system timezone as GMT
sdf.setTimeZone(timeZone); // formatter also has a timezone
date = new Date();
System.out.println(date);
System.out.println(date.getTime()); // prints the same value as above, "not including timezone offset"
System.out.println(sdf.format(date));
// GMT and PDT times are same as getTime() only returns time in ms since UTC for the day ignoring timezone which is mostly used for formatting
Wed Mar 14 22:43:43 GMT 2018
1521067423108
2018-03-14T22:43:43+0000
Wed Mar 14 15:43:43 PDT 2018
1521067423125 // not includes timezone in getTime()
2018-03-14T15:43:43-0700 // formatting looks fine
The good explanation of why Date object taking Current time zone value ,
please refer this SO answer
EDIT.
here I am gonna add some important part of that answers.
java.util.Date is has no specific time zone, although its value is most commonly thought of in relation to UTC. What makes you think it's in local time?
To be precise: the value within a java.util.Date is the number of milliseconds since the Unix epoch, which occurred at midnight January 1st 1970, UTC. The same epoch could also be described in other time zones, but the traditional description is in terms of UTC. As it's a number of milliseconds since a fixed epoch, the value within java.util.Date is the same around the world at any particular instant, regardless of local time zone.
java's SimpleDateFormat parse method supports timezone short name, long name and offset.
Why support for timezone Id is not given??
For eg.
SimpleDateFormat sdf = new SimpleDateFormat("z");
sdf.parse("IST"); //works fine
SimpleDateFormat sdf = new SimpleDateFormat("z");
sdf.parse("Indian Standard Time"); //Also works fine
Why java doesn't support this:
SimpleDateFormat sdf = new SimpleDateFormat("z");
sdf.parse("Asia/Kolkata"); //does not work
We shoud ask JDK developers why they decided that SimpleDateFormat should not support timezone Id. Also SimpleDateFormat API is not clear what timezone format it expects for 'z'. But I know what it supports. It checks timezone against data returned by DateFormatSymbols.getZoneStrings(). It is an array of timezones, each timezone is an array of Strings
•[0] - time zone ID
•[1] - long name of zone in standard time
•[2] - short name of zone in standard time
•[3] - long name of zone in daylight saving time
•[4] - short name of zone in daylight saving time
The zone ID is not localized; others are localized names. See API for details.
We can get all avaliable timezones as
DateFormatSymbols dfs = DateFormatSymbols.getInstance();
for(String[] s : dfs.getZoneStrings()) {
System.out.println(Arrays.toString(s));
}
result (it depends on locale)
...
[Asia/Calcutta, India Standard Time, IST, India Daylight Time, IDT]
...
So SimpleDateFormat (in my locale) allows India Standard Time, IST, India Daylight Time or IDT for 'z', but it does not allow Asia/Calcutta (Timezone ID)
If you use Java 8 you can use new Date and Time API. "VV" means a timezone ID.
See https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
Example:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm VV");
ZonedDateTime zonedDateTime = ZonedDateTime.parse("06/23/2015 21:00 US/Pacific", formatter);