Something weird is happening while parsing a UTC/GMT date. I set the date format as
"yyyy-MM-dd'T'HH:mm:ss'Z'"
where Z is for UTC. And I give following date string to parse:
String startTimestampString = "2013-10-02T00:00:00Z";
I hope to get same date as output but instead it shows
2013-10-01 17:00:00.0
Now sure from where this 7 hour lag coming from?
Code:
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
public class DateTest {
public static void main(String[] args) throws ParseException {
SimpleDateFormat date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
date.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(TimeZone.getTimeZone("UTC").toString());
String startTimestampString = "2013-10-02T00:00:00Z";
long startTimestamp = date.parse(startTimestampString).getTime();
System.out.println(String.format("Long %d and timestamp %s", startTimestamp, new Timestamp(startTimestamp).toString()));
}
}
Output:
sun.util.calendar.ZoneInfo[id="UTC",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]
Long 1380672000000 and timestamp 2013-10-01 17:00:00.0 // ERROR timestamp should have been 2013-10-02 00:00:00.0
java.util.Date Has No Time Zone
As the comments said, your problem is not understanding the confusing way in which java.util.Date works.
A Date object has no time zone, but seems to have one because its toString method applies your JVM's default time zone when generating the textual representation (the String being returned).
This poor design choice by the Java team has caused so much confusion, including countless similar Questions on StackOverflow.
The Date Is Not The String
A key idea here is that the String generated by the toString method is an entirely new object. This string is not the Date. The string is a particular representation of that moment in history as seen from you default time zone. The same moment in history appears as two different time-of-day values when seen from the Paris or Montréal or Kolkata time zones.
Avoid java.util.Date
Do not waste your time with java.util.Date and .Calendar and SimpleDateFormat. They are notoriously troublesome. Use Joda-Time or new java.time package in Java 8 (inspired by Joda-Time).
Joda-Time
Example code in Joda-Time 2.3. Your format is in the standard ISO 8601 format. Joda-Time uses ISO 8601 as its defaults, so no need for parsers/formatters in your case. Joda–Time automatically uses built-in formatters to parse ISO 8601 compliant strings.
String input = "2013-10-02T00:00:00Z";
DateTimeZone timeZoneParis = DateTimeZone.forID( "Europe/Paris" );
DateTime dateTimeParis = new DateTime( input, timeZoneParis );
DateTime dateTimeMontréal = dateTimeParis.withZone( DateTimeZone.forID( "America/Montreal" ) );
DateTime dateTimeIndia = dateTimeParis.withZone( DateTimeZone.forID( "Asia/Kolkata" ) );
DateTime dateTimeUtc = dateTimeParis.withZone( DateTimeZone.UTC );
DateTimeFormatter formatter = DateTimeFormat.forStyle( "FF" ).withLocale( Locale.CANADA_FRENCH );
Dump to console…
System.out.println( "dateTimeParis: " + dateTimeParis );
System.out.println( "dateTimeMontréal: " + dateTimeMontréal );
System.out.println( "dateTimeMontréal formatted: " + formatter.print( dateTimeMontréal ) );
System.out.println( "dateTimeIndia: " + dateTimeIndia );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
When run…
dateTimeParis: 2013-10-02T02:00:00.000+02:00
dateTimeMontréal: 2013-10-01T20:00:00.000-04:00
dateTimeMontréal formatted: mardi 1 octobre 2013 20 h 00 EDT
dateTimeIndia: 2013-10-02T05:30:00.000+05:30
dateTimeUtc: 2013-10-02T00:00:00.000Z
Related
I am trying to add 17 days to 10-APR-2014 and convert the date to dd-MMM-yyyy format, but I am getting Sun Apr 27 00:00:00 GMT+05:30 2014.
Here is my code:
import java.util.*;
import java.text.*;
public class HelloWorld{
public static void main(String []args){
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");
Calendar c = Calendar.getInstance();
c.setTime(new Date());
c.add(Calendar.DATE, 17);
String output = sdf.format(c.getTime());
System.out.println(output);
System.out.print(new SimpleDateFormat("dd-MMM-yyyy").parse(output));
}
}
How can I make the output be 27-Apr-2014?
You are printing a Date parsed from a String formatted from the calendar date.
Instead, print the formatted calendar date:
System.out.print(new SimpleDateFormat("dd-MMM-yyyy").format(c.getTime()));
If displaying and using the dates is disjunct, do this:
Date date; // from Calendar or wherever
String str = new SimpleDateFormat("dd-MMM-yyyy").format(date));
// display str
Then when you want to do something with a selected date:
String selection;
Date date = new SimpleDateFormat("dd-MMM-yyyy").parse(selection));
// do something with date
The answer by Bohemian is correct. Here I present an alternative solution.
Avoid j.u.Date
The java.util.Date and .Calendar classes bundled with Java are notoriously troublesome. Avoid them. Use either Joda-Time or the new java.time package in Java 8.
Date-Only
If you need only a date, without any time component, both Joda-Time and java.time offer a LocalDate class.
Time Zone
Even for a date-only, you still need a time zone to get "today". At any moment the date may vary ±1 depending on your location on the globe. If you do not specify a time zone, the JVM's default time zone will be applied.
Example Code
Here is some example code in Joda-Time 2.3.
Determine "today" based on some time zone. Add seventeen days.
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" );
LocalDate today = new LocalDate( timeZone );
LocalDate seventeenDaysLater = today.plusDays( 17 );
Generate a String representation of the date-time value…
DateTimeFormatter formatter = DateTimeFormat.forPattern( "dd-MMM-yyyy" );
String output = formatter.print( seventeenDaysLater );
Dump to console…
System.out.println( "today: " + today );
System.out.println( "seventeenDaysLater: " + seventeenDaysLater );
System.out.println( "output: " + output );
When run…
today: 2014-04-21
seventeenDaysLater: 2014-05-08
output: 08-May-2014
I try to parse a String and set a time zone, but I can't produce the desired result.
String dtc = "2014-04-02T07:59:02.111Z";
SimpleDateFormat readDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
Date date = null;
try {
date = readDate.parse(dtc);
Log.d("myLog", "date "+date);
} catch (ParseException e) {
Log.d("myLog", "dateExcep " + e);
}
SimpleDateFormat writeDate = new SimpleDateFormat("dd.MM.yyyy, HH.mm");
writeDate.setTimeZone(TimeZone.getTimeZone("GMT+04:00"));
String dateString = writeDate.format(date);
At the output of the variable "dateString" still gives the time 07:59:02 , and I want to make it +4 hours in advance that is 11:59:02
You need to instruct the read-formatter to interprete the input as UTC (GMT - remember that Z stands for UTC in ISO-8601-format):
String dtc = "2014-04-02T07:59:02.111Z";
SimpleDateFormat readDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
readDate.setTimeZone(TimeZone.getTimeZone("GMT")); // missing line
Date date = readDate.parse(dtc);
SimpleDateFormat writeDate = new SimpleDateFormat("dd.MM.yyyy, HH.mm");
writeDate.setTimeZone(TimeZone.getTimeZone("GMT+04:00"));
String s = writeDate.format(date);
Then you will get:
02.04.2014, 11.59
Joda-Time
Doing date-time work much easier and simpler with the Joda-Time library than with the notoriously troublesome bundled java.util.Date & .Calendar classes.
Time Zone
Using proper time zone names, rather than a specific offset, is generally a wiser approach.
Example Code
Here is some example code using Joda-Time 2.3.
Notice:
Joda-Time has built-in parsers for strings in ISO 8601 format. No need to instantiate parsing or formatting objects.
Joda-Time is both parsing the UTC string and adjusting it to another time zone all in one call to the DateTime constructor.
When converting to a UTC-based dateTime in the last line, we still have the same moment in the timeline of the Universe (same count of milliseconds since Unix epoch).
Source…
String input = "2014-04-02T07:59:02.111Z";
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Dubai" );
DateTime dateTimeDubai = new DateTime( input, timeZone ); (a) Parse, (b) Adjust time zone.
DateTime dateTimeUtc = dateTimeDubai.withZone( DateTimeZone.UTC );
Dump to console…
System.out.println( "input: " + input );
System.out.println( "dateTimeDubai: " + dateTimeDubai );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
When run…
input: 2014-04-02T07:59:02.111Z
dateTimeDubai: 2014-04-02T11:59:02.111+04:00
dateTimeUtc: 2014-04-02T07:59:02.111Z
you can take whatever pattern you want like i have date+ time zone. so you can set according to you. here is my code.
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
here i have set the date format.
String currentDate = dateFormat.format(currentLocalTime);
String localTime = date.format(currentLocalTime);// to get the time zone i have used this.
String newtime=currentDate+localTime;// and then i have apeend this now print log you will get the desire result.
I am trying to convert between a date printed out in an EST timezone into a date printed out in GMT/UTC
package com.stefano;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class MainEntry {
/**
* #param args
* #throws ParseException
*/
public static void main(String[] args) throws ParseException {
String dateTime = "1307011200"; //12:00PM 01 July 2013
System.out.println("Input -> " + dateTime);
SimpleDateFormat format = new SimpleDateFormat("yyMMddHHmm");
format.setTimeZone(TimeZone.getTimeZone("EST"));
Date date = format.parse(dateTime);
System.out.println("Intermediate -> " + date);
format.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("Output -> " + format.format(date));
}
}
The output it gives is:
Input -> 1307011200
Intermediate -> Mon Jul 01 17:00:00 BST 2013
Output -> 1307011600
Even though the time difference between EST and GMT is always 5, it is somehow getting involved with BST.
I cannot use Joda-Time.
The javadoc of the SimpleDateFormat.parse(String) method refers to the parse(String, ParsePosition) method, that says:
This parsing operation uses the calendar to produce a Date. As a result, the calendar's date-time fields and the TimeZone value may have been overwritten, depending on subclass implementations. Any TimeZone value that has previously been set by a call to setTimeZone may need to be restored for further operations.
According to this you can't use this method to tell the SimpleDateFormat which timezone
the given date is in.
You can fix this method like this:
String dateTime = "1307011200"; // 12:00PM 01 July 2013
dateTime += " EST"; // append the timezone information to the input string
System.out.println("Input -> " + dateTime);
SimpleDateFormat format = new SimpleDateFormat("yyMMddHHmm z"); // tell the formatter to look for the timezone info
Date date = format.parse(dateTime);
System.out.println("Intermediate -> " + date);
format.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("Output -> " + format.format(date));
This will also print the Date object using your local timezone, but it shows a way to parse the dateTime string using a given timezone.
The answer by zovits is correct.
US East Coast Offset
If by EST you mean the east coast of the United States (and parts of Canada), then your statement the time difference between EST and GMT is always 5 is incorrect. With Daylight Saving Time (DST), the offset may be -05:00 or -04:00. Indeed, your specified date-time does have DST in effect.
Avoid 3-4 Letter Time Zone Codes
Those three or four letter time zone codes are neither standardized nor unique. Avoid them. Use proper time zone names, most of which are continent+city.
Comparison To Joda-Time
For comparison, here is some Joda-Time example code. The java.util.Date & .Calendar classes bundled with Java are so notoriously troublesome that every Java programmer should move to either Joda-Time or the new Java 8 java.time package (inspired by Joda-Time, defined by JSR 310).
While a java.util.Date seems to have a time zone but actually does not, note that a Joda-Time DateTime does truly know its own assigned time zone.
Joda-Time uses the ISO 8601 standard for its defaults. You can use other formats as well, as seen with the Montréal example below.
Example Code
String input = "1307011200"; //12:00PM 01 July 2013
DateTimeFormatter formatterSmooshed = DateTimeFormat.forPattern( "yyMMddHHmm" );
DateTimeZone timeZoneNewYork = DateTimeZone.forID( "America/New_York" );
DateTime dateTimeNewYork = formatterSmooshed.withZone( timeZoneNewYork ).parseDateTime( input );
DateTime dateTimeUtc = dateTimeNewYork.withZone( DateTimeZone.UTC );
String outputMontréal = DateTimeFormat.forStyle( "FF" ).withLocale( Locale.CANADA_FRENCH ).print( dateTimeNewYork );
String outputSmooshed = formatterSmooshed.print( dateTimeNewYork ); // Expect same as input.
Dump to console…
System.out.println( "input: " + input );
System.out.println( "dateTimeNewYork: " + dateTimeNewYork );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "outputMontréal: " + outputMontréal );
System.out.println( "outputSmooshed: " + outputSmooshed );
When run…
input: 1307011200
dateTimeNewYork: 2013-07-01T12:00:00.000-04:00
dateTimeUtc: 2013-07-01T16:00:00.000Z
outputMontréal: lundi 1 juillet 2013 12 h 00 EDT
outputSmooshed: 1307011200
I am trying to parse/validate the date 2013-06-19T12:00-05:00 using Java 6
I have tried several patterns, including following:
yyyy-MM-dd'T'HH:mmz
yyyy-MM-dd'T'HH:mmZ
yyyy-MM-dd'T'HH:mm'Z'
yyyy-MM-dd'T'HH:mm Z
yyyy-MM-dd'T'HH:mm z
yyyy-MM-dd'T'HH:mm'z'
yyyy-MM-dd'T'HH:mm-Z
yyyy-MM-dd'T'HH:mm-z
yyyy-MM-dd'T'hh:mm:ssZ
yyyy-mm-DD'T'hh:mm:ssZ
yyyy-MM-DD'T'hh:mm:ssZ
yyyy-MM-dd'T'HH:mm:ssZ
yyyy-MM-dd'T'HH:mm:ssz
but keep getting ParseException.
What would be the appropriate format/pattern for parsing 2013-06-19T12:00-05:00?
Thanks.
I would suggest that you use the excellent Joda-Time library to do this, specifically the parse(String str) method of the DateTime class, which will parse your example date using the default ISODateTimeFormat.dateTimeParser()
The JavaDoc for DateTime.parse(String str) is at http://www.joda.org/joda-time/apidocs/org/joda/time/DateTime.html#parse%28java.lang.String%29 and you can read more about Joda-Time at http://www.joda.org/joda-time/
String dateString = "2013-06-19T12:00-05:00";
String pattern = "yyyy-MM-dd'T'HH:mmZ";
DateTimeFormatter dtf = DateTimeFormat.forPattern(pattern);
DateTime dateTime = dtf.parseDateTime(dateString);
Date ans=dateTime.toDate();
System.out.println(ans);
Use simpledateformat with pattern like "yyyy-MM-dd'T'HH-mm:ss:SS"
The Joda-Time 2.3 library is already built to handle that variation of ISO 8601 format. No need to create a formatter.
I arbitrarily chose Montréal Québec as a time zone because of your -05:00 time zone offset. You may rather work with UTC/GMT date-times in which case you can pass a pre-defined instance: DateTimeZone.UTC.
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
String dateTimeString = "2013-06-19T12:00-05:00";
DateTimeZone timeZone = DateTimeZone.forID( "America/Montreal" ); // Or for UTC/GMT, use: DateTimeZone.UTC
DateTime dateTime = new DateTime( dateTimeString, timeZone );
Dump to console…
System.out.println( "dateTimeString: " + dateTimeString );
System.out.println( "dateTime: " + dateTime );
System.out.println( "dateTime in UTC/GMT: " + dateTime.toDateTime( DateTimeZone.UTC ) );
When run…
dateTimeString: 2013-06-19T12:00-05:00
dateTime: 2013-06-19T13:00:00.000-04:00
dateTime in UTC/GMT: 2013-06-19T17:00:00.000Z
Note the one hour difference because Montréal Québec was in Daylight Saving Time (DST) on that date.
The date 2013-06-19T12:00-05:00 can't be parsed under Java 6 in current form. On other hand using Joda-Time seems to be an overkill.
To solve problem I added timezone to the date:
public Date extractDate(String dateStr) {
Pattern aPattern = Pattern.compile("\\d+([+-]\\d+:\\d+)$", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
Matcher matcher = aPattern.matcher(dateStr);
if(matcher.find()){
String timezone = matcher.group(1);
System.out.println("timezone:" + timezone);
dateStr = StringUtils.replace(dateStr, timezone, "GMT" + timezone);
}
Date date = null;
String [] datePatterns = {"yyyy-MM-dd'T'HH:mmZ"};
try {
date = DateUtils.parseDateStrictly(dateStr, datePatterns);
}
catch (Exception except) {
except.printStackTrace();
}
return date;
}
I am getting date as below in json response .
{"dateTime":"2012-03-03T10:00:00.890+05:30"}
I wated to display it like 3 march 2012 10Am in java . How to format this date
If you want to do it in Java, Use SimpleDateFormat like this:
EDIT:
To match with your scenario I have edited it as follows:
String input = "2012-03-03T10:00:00.890+05:30";
In the above input string you will have to remove the : colon from the time zone part i.e. +05:30. You could use regex to do this as shown in this post. And then use following code to convert it in your format:
DateFormat oldFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
DateFormat newFormat = new SimpleDateFormat("dd MMMMM yyyy hha");
String dateStr = newFormat.format(oldFormat.parse(input));
In JS,this date is in standart format so new date(object.dateTime) will parse your date. Then by using toGMTString or toLocalString you will have the right format.
You just have to strip the 4 first and 4 last characters of the string returned.
what language are you using to display the date?
You would have to parse the value as a date, then you can change the format of the display of that date.
The answer by Kuldeep Jain is correct. But using the java.util.Date/Calendar classes should be avoided as they are badly designed and implemented.
Instead use Joda-Time, or in Java 8, the new java.time.* classes (inspired by Joda-Time).
While Joda-Time allows you to define your own specific formats for parsing, in your case you needn't. The constructors on Joda-Time's DateTime class are already built to parse the ISO 8601 format you are using.
Example code…
// © 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.*;
DateTimeZone timeZone_Kolkata = DateTimeZone.forID( "Asia/Kolkata" );
String input = "2012-03-03T10:00:00.890+05:30";
DateTime dateTime = new DateTime( input );
DateTime dateTimeInUtc = dateTime.toDateTime( DateTimeZone.UTC );
DateTime dateTimeInKolkata = dateTime.toDateTime( timeZone_Kolkata );
DateTimeFormatter formatter = DateTimeFormat.forStyle("LS").withLocale( new Locale( "en", "IN" ) ); // English, India.
String output = formatter.print( dateTime );
Dump to console…
System.out.println( "dateTime: " + dateTime );
System.out.println( "dateTimeInUtc: " + dateTimeInUtc );
System.out.println( "dateTimeInKolkata: " + dateTimeInKolkata );
System.out.println( "output: " + output );
When run…
dateTime: 2012-03-02T20:30:00.890-08:00
dateTimeInUtc: 2012-03-03T04:30:00.890Z
dateTimeInKolkata: 2012-03-03T10:00:00.890+05:30
output: 2 March, 2012 8:30 PM