Get correct long value from parsed Date (Timezone issue) - java

I'm trying to parse a date from a String and get the long value. The long value will be later sent to an SQL query.
here's my code:
String dayDate = "28-02-2013";
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
Date day = new Date();
try {
day = sdf.parse(dayDate);
} catch (ParseException pe) {
pe.printStackTrace();
}
System.out.println("day : "+day.toString()+ " long : " + day.getTime());
which gives the following output:
day : Thu Feb 28 00:00:00 EET 2013 long : 1362002400000
which is correct but not what I want since the long value results in Wed, 27 Feb 2013 22:00:00 GMT (http://www.epochconverter.com/) (I'm in a GMT+2 timezone). And i need to send to correct long value to sql.
Is there anyway to work around this without using external libraries?

SimpleDateFormat is locale-aware, meaning the date it parses is in your timezone. Midnight 28 Feb in GMT+2 is actually 10pm 27 Feb in GMT, the long value 1362002400000. I would add this to get the parsing right (would't bother using Calendar):
sdf.setTimeZone(TimeZone.getTimeZone("GMT"))
Again, when you print this date it uses SimpleDateFormat and that's why you can see EET in the output.
Passing this to database is a different story though once you get this right.

Use DateFormat.setCalendar(Calendar cal) to set a Calendar with GMT as its timezone, or use DateFormat.setTimeZone(TimeZone zone) with the GMT TimeZone. That will ensure that the resulting Date will be 00:00:00 in GMT instead of in EET.

If you add a timezone specifier to your string you can force java to use GMT for the conversion:
String dayDate = "28-02-2013";
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy z"); // z is a timezone specifier
Date day = new Date();
try {
day = sdf.parse(dayDate + " GMT"); // Use GMT timezone.
} catch (ParseException pe) {
pe.printStackTrace();
}
System.out.println("day : "+day.toString()+ " long : " + day.getTime());

You are converting between text and internal (Date) representations of dates and times without explicitly stating the time-zone. That never goes well.

Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
Date date = calendar.getTime();
Use your timezone String:
TimeZones

Related

SimpleDateFormat results in incorrect time

I have the following code
protected void amethod1() {
String strDate = "Thu May 18 16:24:59 UTC 2017";
String dateFormatStr = "EEE MMM dd HH:mm:ss zzz yyyy";
DateFormat dateFormat = new SimpleDateFormat(dateFormatStr);
Date formattedDate = null;
try {
formattedDate = dateFormat.parse(strDate);
} catch (ParseException e) {
e.printStackTrace();
}
}
The resulting value of formattedDate is- "Thu May 18 11:24:59 CDT 2017" .
I am testing this code in Chicago and the local timezone is CDT.
I am not able to understand why the time value changes from 16:24:59 to 11:24:59 even though. Am I missing something in the defined format of the date?
Class Date doesn't contain any timezone at all. It's just a number of milliseconds since 01.01.1970 00:00:00 GMT. If you try to see, what formattedDate contains with System.out.println or debugger, you'll get formatted date for your local timezone. 11:24:59 CDT and 16:24:59 UTC are the same time, so result is correct.
Is java.util.Date using TimeZone?
It is better to use jodatime or Java 8 Time API in order to better manage time and timezones.
First, you are getting the correct time. When Daylight Savings Time is in use in Chicago (which it is on May 18), the time is 11:24:59 when it’s 16:24:59 in UTC. So your Date value represents the same point in time. This is all you can expect from a Date.
I understand that you want not just a point in time, but also the UTC time zone. Since Axel P has already recommended Java 8 date and time API, I just wanted to fill in the details:
DateTimeFormatter parseFormatter = DateTimeFormatter.ofPattern(dateFormatStr, Locale.US);
ZonedDateTime dateTime = ZonedDateTime.parse(strDate, parseFormatter);
The result is
2017-05-18T16:24:59Z[UTC]
If you always want the UTC time zone, the Instant class is just right for it, so you will probably want to convert to it:
Instant instant = dateTime.toInstant();
Instants are always in UTC, popularly speaking.
SimpleDateFormat myFmt=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date now=new Date();
System.out.println(myFmt.format(now));
I hope I can help you. If you can,please adopt.Thank you
The resulting value of formattedDate is- "Thu May 18 11:24:59 CDT 2017" . Why? because your time zone running -5 hour from UTC time you will find in below link wiki time zone abbreviations, if you want result in same timezone you need to specify timezone in formater Hope you get my concern
https://en.wikipedia.org/wiki/List_of_time_zone_abbreviations
public static void amethod1() {
String strDate = "Thu May 18 16:24:59 UTC 2017";
String dateFormatStr = "EEE MMM dd HH:mm:ss zzz yyyy";
SimpleDateFormat dateFormat = new SimpleDateFormat(dateFormatStr);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date formattedDate = null;
try {
formattedDate = dateFormat.parse(strDate);
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println("formattedDate: "+dateFormat.format(formattedDate));
}
You specified timezone, that's why after parsing time on current timezone (where you are), SimpleDateFormat sets UTC timezone. When you try to output your date, it is displayed on your current timezone
It appears you would need to specify the TimeZone as well when you format the Date For eg. .TimeZone.setDefault(TimeZone.getTimeZone("PST"));
Have a look at this discussion TimeZone
The output of a Date depends on the format specified, where you can specify the timezone, as shown in the example below:
protected void amethod2() {
String strDate = "Thu May 18 16:24:59 UTC 2017";
String dateFormatStr = "EEE MMM dd HH:mm:ss zzz yyyy";
DateFormat dateFormat = new SimpleDateFormat(dateFormatStr);
Date formattedDate = null;
try {
formattedDate = dateFormat.parse(strDate);
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println("Date: " + formattedDate);
// Thu May 18 17:24:59 BST 2017, BST is my system default timezone
// Set the time zone to UTC for the calendar of dateFormat
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println("Date in timezone UTC: " + dateFormat.format(formattedDate));
// Thu May 18 16:24:59 UTC 2017
// Set the time zone to America/Chicago
dateFormat.setTimeZone(TimeZone.getTimeZone("America/Chicago"));
System.out.println("Date in timezone America/Chicago: " + dateFormat.format(formattedDate));
// Thu May 18 11:24:59 CDT 2017
}
As for the IDs, such as "UTC" and "America/Chicago" in the example, you can get a complete list of them via TimeZone.getAvailableIDs(). You can print them out to have a look:
Arrays.stream(java.util.TimeZone.getAvailableIDs()).forEach(System.out::println);
And you'll have:
Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
Africa/Bamako
Africa/Bangui
Africa/Banjul
Africa/Bissau
Africa/Blantyre
...

Java TimeZone Conversion producing opposite results.

Here is the sample I am using.
import java.util.*;
import java.text.*;
public class TimeZoneTest
{
public static final String UTC_ZONE = "UTC";
static String utcDateString = "01/11/2016 11:00:00";
public static void main (String [] args)
{
DateFormat df;
try{
df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
System.out.println("Original Date : " + utcDateString);
df.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = df.parse(utcDateString);
System.out.println(" In its Date format : " + date.toString());
System.out.println(" In its GMT format : " + date.toGMTString());
System.out.println(" In its Local format : " + date.toLocaleString());
}
catch (ParseException ex)
{
System.out.println("Exception!!!!");
}
}
}
Here is the output produced.
Original Date : 01/11/2016 11:00:00
In its Date format : Mon Jan 11 06:00:00 EST 2016
In its GMT format : 11 Jan 2016 11:00:00 GMT
In its Local format : Jan 11, 2016 6:00:00 AM
When using the time 11:00:00 and setting the TimeZone to UTC, I was expecting that the 11:00:00 which is my local time (Eastern) representation would then be converted to UTC which would produce 16:00:00.
Instead, it seems to take the string value 11:00:00 and process it as the UTC time instead of local time and return back my local time which is 06:00:00.
Is this the expected results?
When you set the timezone, is it supposed to convert the time being parsed (11:00:00 ) to that timezone and produce (16:00:00)?
OR
When you set the timezone, is it supposed to treat the time being parsed (11:00:00 ) as though it was in that timezone and return the local time (06:00:00)?
You're last statement is true: "OR When you set the timezone, is it supposed to treat the time being parsed (11:00:00 ) as though it was in that timezone and return the local time (06:00:00)?"
Basically, you set the timezone in the DateFormat, then you parse a date without timezone information, so it'll use the timezone from the DateFormat, to convert the String to certain amount of milliseconds from January 1, 1970. Then, you print that date with "toString" that will convert it back to String using your machine's timezone. But the date is the same throughout the program, just different format/timezone.

Convert UTC Date to local Date

I am converting from epoch time (which is in UTC) to a format as shown below. Now I tried different SO answers to convert UTCDate from UTC to local time. But I am not getting the local time.
Any help would be appreciated.
String epochTime = "1436831775043";
Date UTCDate = new Date(Long.parseLong(epochTime));
Date localDate; // How to get this?
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("h:mm a");
String result = simpleDateFormat.format(UTCDate);
Also, the conversion has to be done without the help of any external library.
Java 8
String epochTime = "1436831775043";
Instant utcInstant = new Date(Long.parseLong(epochTime)).toInstant();
ZonedDateTime there = ZonedDateTime.ofInstant(utcInstant, ZoneId.of("UTC"));
System.out.println(utcInstant);
LocalDateTime here = there.withZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime();
System.out.println(here);
Which outputs:
2015-07-13T23:56:15.043Z
2015-07-14T09:56:15.043
After thoughts...
I think you're chasing your tail. Date is just a container for the number of milliseconds since the epoch (January 1, 1970, 00:00:00 GMT). It doesn't internally carry a representation of a time zone (AFAIK).
For example...
String epochTime = "1436831775043";
Date UTCDate = new Date(Long.parseLong(epochTime));
// Prints the "representation" of the Date
System.out.println(UTCDate);
// Local date/time format...
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM/yyyy h:mm:ss a");
try {
System.out.println("local format: " + simpleDateFormat.format(UTCDate));
System.out.println("local Date: " + simpleDateFormat.parse(simpleDateFormat.format(UTCDate)));
} catch (ParseException ex) {
Logger.getLogger(JavaApplication203.class.getName()).log(Level.SEVERE, null, ex);
}
// UTC date/time format
try {
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println("utc format: " + simpleDateFormat.format(UTCDate));
System.out.println("utc date: " + simpleDateFormat.parse(simpleDateFormat.format(UTCDate)));
} catch (ParseException ex) {
Logger.getLogger(JavaApplication203.class.getName()).log(Level.SEVERE, null, ex);
}
Which outputs...
Tue Jul 14 09:56:15 EST 2015
local format: 14/07/2015 9:56:15 AM
local Date: Tue Jul 14 09:56:15 EST 2015
utc format: 13/07/2015 11:56:15 PM
utc date: Tue Jul 14 09:56:15 EST 2015
If you have a look at local Date and utc date they are the same thing, even though the local format and utc format are formatted correctly.
So, instead of chasing your tale trying to get Date to "represent" a value you want, either use Java 8's Time API or JodaTime to manage the Time Zone information or simply format the Date into the Time Zone you want...
Further, if we do something like...
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM/yyyy h:mm:ss a");
Date localDate = simpleDateFormat.parse(simpleDateFormat.format(UTCDate));
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date utcDate = simpleDateFormat.parse(simpleDateFormat.format(UTCDate));
System.out.println(localDate.getTime());
System.out.println(utcDate.getTime());
System.out.println(localDate.equals(utcDate));
It will print...
1436831775000
1436831775000
true
You can set your time zone in the formatter:
simpleDateFormat.setTimeZone(TimeZone.getDefault());

Java setting timezone while converting date from Mountain to Eastern to GMT

I am trying to convert mountain time to eastern time to GMT time. But when I am getting the final date in the date field "gmtDate",it's back to my local date in mountain time.
Here are my questions:
I am expecting to see 2 hrs of difference from mountain time to eastern time. But seeing only an hor of difference. What is wrong here?
Again there should a six hours of difference from eastern time to GMT time but it is 5 hours of difference showing here. What is wrong?
Finally, I tried to save the date and time as GMT but looks like it's coming back to mountain time. What is wrong here?
Here is my final output:
DEBUG [main] (MyClass.java:100) - local : 2014-07-14 10:11:04 MDT
DEBUG [main] (MyClass.java:108) - est : 2014-07-14 11:11:04 EST
DEBUG [main] (MyClass.java:110) - =================================================
DEBUG [main] (MyClass.java:113) - gmt : 2014-07-14 16:11:04 GMT
DEBUG [main] (MyClass.java:125) - gmt date : Mon Jul 14 10:11:04 MDT 2014
DEBUG [main] (MyClass.java:127) - =================================================
Here is my example code:
private Date testTimeZone(Date date, TimeZone sourceTimeZone, TimeZone targetTimeZone) {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
Date localdate = null;
try {
localdate = df.parse("2014-07-14 09:11:04 MST");
} catch (ParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
LOG.debug("local : " + df.format(localdate));
df.setTimeZone(TimeZone.getTimeZone("EST"));
LOG.debug("est : " + df.format(localdate));
LOG.debug("=================================================");
df.setTimeZone(TimeZone.getTimeZone("GMT"));
LOG.debug("gmt : " + df.format(localdate));
Date gmtDate = null;
try {
gmtDate = df.parse(df.format(localdate));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
LOG.debug("gmt date : " + gmtDate);
LOG.debug("=================================================");
return gmtDate;
}
So I ran your code and instead of getting mountain time, I got gmt date : Mon Jul 14 12:11:04 EDT 2014
This timezone corresponds to my timezone which lead me to the discovery that Date.toString() uses the local timezone to format the date. Per the Java date specification, a Date is:
A thin wrapper around a millisecond value that allows JDBC to identify this as an SQL DATE value. A milliseconds value represents the number of milliseconds that have passed since January 1, 1970 00:00:00.000 GMT.
So the whole DateFormat code you are dealing doesn't actually change a value. It just matters how it is output. The underlying number of milliseconds will never actually change
Also, EST is for the winter, and EDT (Eastern Daylight Time) is used in the summer (Change this and your first two questions are resolved)
Java Date represents a moment in time, and does not include an internal TimeZone. Instead, you use the SimpleDateFormat (such as you already have!) to perform the display formatting.
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
try {
Date date = df.parse("2014-07-14 09:11:04 MST");
df.setTimeZone( TimeZone.getTimeZone( "EST" ) );
System.out.println(df.format(date));
df.setTimeZone( TimeZone.getTimeZone( "GMT" ) );
System.out.println(df.format(date));
} catch (ParseException e) {
e.printStackTrace();
}
Which outputs
2014-07-14 11:11:04 EST
2014-07-14 16:11:04 GMT
The reason you get gmt date : Mon Jul 14 10:11:04 MDT 2014 is because the TimeZone associated with the DateFormat is changed to MDT when you parse localdate - which is local : 2014-07-14 10:11:04 MDT in your example.
The default timezone is your local timezone, so you should have used:
df.setTimeZone(TimeZone.getTimeZone("GMT");
LOG.debug("gmt date : " + df.format(gmtDate));
You probably want to be using UCT (Universal Coordated Time) .. that is what you want to store and retrieve (if you use a database or other store. GMT represents an actual timezone now, UCT is the "reference" time.

How to get Current Date using GMT in android?

I want Current Date in GMT wise Timezone.I used following code.
public static Date getGMTDate(String dateFormat) throws ParseException
{
SimpleDateFormat dateFormatGmt = new SimpleDateFormat(dateFormat);
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
// Local time zone
SimpleDateFormat dateFormatLocal = new SimpleDateFormat(dateFormat);
// Time in GMT
return dateFormatLocal.parse(dateFormatGmt.format(new Date()));
}
//call above function.
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
date = getGMTDate("yyyy-MM-dd HH:mm:ss");
when i will change my device date then time is display in GMT formate but Date is not display in GMT timezone.its display of device's date.
but I want Current GMT Date.
This may works
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("dd:MM:yyyy HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(new Date())+"");
Specify the format, and you will get it in GMT!
EDIT: You can also check This
I changed your method as below
public static String getGMTDate() {
DateFormat dateFmt = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.MEDIUM, SimpleDateFormat.MEDIUM);
dateFmt.setTimeZone(TimeZone.getTimeZone("GMT"));
// Time in GMT
return dateFmt.format(new Date());
}
And got the following date (which is same as what you wanted I believe)
07-18 10:41:54.525: D/test(6996): GMT Date is: **Jul 18, 2013 10:41:03 AM**
So simply call this method and it will return the GMT date in string format.
EDIT 1:
you are setting GMT time zone and not GMT Date. You are not trying to understand your code. When you called new Data() it returned your device date, and then you formatted it for the corresponding GMT date and time. So if your change your device date to 16th July then your code (or even my code) will return the GMT equivalent of 16th July time. If you want 18th July GMT time even when your device's date is 16th July 2000, then I don't think you can do it without getting it from some network entity.
EDIT 2:
You should look at this SO reference to a similar kind of problem and it may serve you well.
Output: 2016-08-01 14:37:48 UTC
final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Works fine.

Categories