Java: Compare dates on same timezone - java

Given:
SimpleDateFormat sd = new SimpleDateFormat ("yy-MM-dd hh:mm:ss.SSS");
sd.setTimeZone(TimeZone.getTimeZone("GMT"));
Date d = sd.parse("a date similar to now on local computer");
if I compare d.getTime() with new Date().getTime(), the values are different with more than one hour. Why?

Check your timezones. You are comparing a time that isn't in GMT.

You're explicitly setting your SimpleDateFormat to parse in GMT, which means that when you parse the current clock time, you're getting the moment of time when that time occurred, in the GMT time zone. If you're not in the GMT time zone, that won't be "now".

Date objects don't know anything about timezones - there is no explicit timezone information in a Date object. A Date object represents an "absolute" moment in time (it's a timestamp). This means you should not think of a Date object as "a date in a certain timezone" - it has no timezone.
Suppose that from some source you get a String that contains a date and time, without an explicit timezone mentioned in it, for example: 2014-12-16 17:30:48.382. Suppose that you know that this date and time is in the GMT timezone.
You could then parse it to a Date object with an appropriate SimpleDateFormat object:
DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
// Set the timezone of the SimpleDateFormat to GMT, because you know the string
// should be interpreted as GMT
fmt.setTimeZone(TimeZone.getTimeZone("GMT"));
// Parse the String into a Date object
Date dateTime = fmt.parse("2014-12-16 17:30:48.382");
// Date object which is set to "now"
Date now = new Date();
// Compare it to "now"
if (dateTime.before(now)) {
System.out.println("The specified date is in the past");
} else if (dateTime.after(now)) {
System.out.println("The specified date is in the future");
} else {
System.out.println("The specified date is now");
}
If you want to print the date in a certain timezone, then do so by formatting it with a SimpleDateFormat set to the appropriate timezone.
DateFormat outfmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z");
outfmt.setTimeZone(TimeZone.getTimeZone("EDT"));
// Will print dateTime in the EDT timezone
System.out.println(outfmt.format(dateTime));

Related

How to convert date object to ones own timezone in android?

In android, I download date information from a MySQL database on a free web server, then convert it to a Date object using:
Note: the server time is 5 hours ahead of toronto.
public static Date getDateFromSQLDate(String sqldate) {
try {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
Date date = (Date) formatter.parse(sqldate);
TimeZone targetTimeZone = TimeZone.getDefault();
TimeZone serverTimeZone = TimeZone.getTimeZone("Europe/London");
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.setTimeZone(serverTimeZone);
calendar.add(Calendar.MILLISECOND, serverTimeZone.getRawOffset() * -1);
if (serverTimeZone.inDaylightTime(calendar.getTime())) {
calendar.add(Calendar.MILLISECOND, calendar.getTimeZone().getDSTSavings() * -1);
}
calendar.add(Calendar.MILLISECOND, targetTimeZone.getRawOffset());
if (targetTimeZone.inDaylightTime(calendar.getTime())) {
calendar.add(Calendar.MILLISECOND, targetTimeZone.getDSTSavings());
}
return calendar.getTime();
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
This doesn't seem to work..
The problem is that the date is relative to the timezone of the server. The one downloading could be confused with the times as they don't know its not in their own timezone.
I have a Date object, is there a way I can retrieve the timezone of the location the users phone is in, and then modify that Date object to be their own timezone?
Thanks
EDIT:
How to get TimeZone from android mobile?
This gets a timezone object, but how do I change a Date object with it?
My app has to deal with server time similar to you.
(All datetime that I got from server represent datetime at UTC +00:00)
// date string to convert
String dateString = "2014-01-07 12:00:00"
// create date formatter, set time zone to UTC and parse
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
TimeZone serverTimeZone = TimeZone.getTimeZone("UTC");
formatter.setTimeZone(serverTimeZone);
Date date = formatter.parse(dateString);
Log.i("Debug", "date object : " + date.toString());
// I'm in Bangkok (UTC +07:00) so I'll see "Wed Jan 07 19:00:00 GMT+07:00 2015"
// If you do this in Toronto, you should see "Wed Jan 07 07:00:00 GMT -05:00 2015"
When you wanna print this date in Toronto, I believe you don't have to calculate DST by yourself because calendar and date formatter should handle that (not sure, I read from somewhere long ago)
// Create timezone for Toronto
TimeZone torontoTimeZone = TimeZone.getTimeZone("America/Toronto");
// Create calendar, set timezone, to see hour of day in Toronto
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(torontoTimeZone);
calendar.setTime(date);
Log.i("Debug", "Hour of day : " + calendar.get(Calendar.HOUR_OF_DAY);
// Hour of day : 7
// Create date formatter, set timezone, to print date for Toronto user.
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy, hh:mm", Locale.US);
formatter.setTimeZone(torontoTimeZone);
String torontoDate = formatter.format(date);
Log.i("Debug", "Date in Toronto : " + torontoDate);
// Date in Toronto : 07 Jan 2015, 07:00
You can set calendar and date formatter to user timezone by replace
TimeZone timezone = TimeZone.getTimeZone("America/Toronto")
with
TimeZone timezone = TimeZone.getDefault()
When I deal with date from server, I'll
request UTC time from server, if server doesn't send me UTC time, convert to UTC time first.
when parse date object from server, I always create date object represent time at UTC (time at server)
perform calculation or anything else with UTC date object.
pass only UTC date object from and to Activity/Fragment/Service/Model
only format date string with user timezone only when I need to display to user.
This is how you can change the date to your timezone
SimpleDateformat sdf = new SimpleDateFormat("yourformat");
TimeZone tz = TimeZone.getDefault();
sdf.setTimezone(tz);
sdf.format(yourdate); //will return a string in "your-format" to represent date
You're on the right track. You need to set the time zone of the Calendar object to the server's time zone. Then you can add the offset (and factor in DST) with the TimeZone that you got from the user's device (the link you included).
Code:
calendar.add(Calendar.MILLISECOND, serverTimeZone.getRawOffset() * -1);
if (serverTimeZone.inDaylightTime(calendar.getTime())) {
calendar.add(Calendar.MILLISECOND, calendar.getTimeZone().getDSTSavings() * -1);
}
calendar.add(Calendar.MILLISECOND, targetTimeZone.getRawOffset());
if (targetTimeZone.inDaylightTime(calendar.getTime())) {
calendar.add(Calendar.MILLISECOND, targetTimeZone.getDSTSavings());
}
After that, you can retrieve the date in the usual way from the Calendar.
Also see this answer for more information.

How to convert an offset from GMT to the local timezone?

I have two inputs:
a date value
an integer (+8 or -3 or such) that represents the offset from GMT
Using Java, how can I convert the given date value into the corresponding date/time in the local timezone? There doesn't seem to be any timezone offset function in the Date class.
Thanks!
(If you don't want to use JodaTime) Use TimeZone with setRawOffset with code from this answer: https://stackoverflow.com/a/19378721/360211
I think you need to use the TimeZone.getAvailableIDs(rawOffsetinMiliSeconds) to get a timezone value.
Working Example:
Date now = new Date();
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf1.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(sdf1.format(now));
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf2.setTimeZone(TimeZone.getTimeZone((TimeZone.getAvailableIDs(5*1000*3600))[0]));
System.out.println(sdf2.format(now));

SimpleDateFormat returns wrong date value during parse

I m facing a problem:I want to get current time of GMT TimeZone in long.
I m using the following code as given below:
TimeZone timeZoneGmt = TimeZone.getTimeZone("GMT");
long gmtCurrentTime = getCurrentTimeInSpecificTimeZone(timeZoneGmt);
public static long getCurrentTimeInSpecificTimeZone(TimeZone timeZone) {
Calendar cal = Calendar.getInstance();
cal.setTimeZone(timeZone);
long finalValue = 0;
SimpleDateFormat sdf = new SimpleDateFormat(
"MMM dd yyyy hh:mm:ss:SSSaaa");
sdf.setTimeZone(timeZone);
Date finalDate = null;
String date = sdf.format(cal.getTime());
try {
finalDate = sdf.parse(date);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finalValue = finalDate.getTime();
return finalValue;
}
As given in, above method
while formatting
String date = sdf.format(cal.getTime());
I m getting correct current time in GMT but as i do parsing by following code:
finalDate=sdf.parse(date);
Date got changed from current GMT time to 15:35:16 IST 2013 that is current time of my system.
I tried with Calendar as well in another way:
TimeZone timeZoneGmt=TimeZone.get("GMT");
Calendar calGmt = Calendar.getInstance();
calGmt.setTimeZone(timeZoneGmt);
long finalGmtValue = 0;
finalGmtValue = calGmt.getTimeInMillis();
System.out.println("Date......" + calGmt.getTime());
but still getting date as current time of my System Thu Jan 23 15:58:16 IST 2014 Not getting GMT current time.
You've misunderstood how Date works. A Date doesn't have a time zone - if you use Date.toString() you'll always see the default time zone. The long value in a Date is purely the number of milliseconds since the Unix epoch: it doesn't have any concept of time zone or calendar system.
If you want to represent a date and time in a particular time zone and calendar, use Calendar instead - but for getting "the current date and time as a long" you can just use System.currentTimeMillis(), which again does not have anything to do with the system time zone.
Additionally, even if you did want to do manipulation like this, you shouldn't be using string conversions. You're not conceptually performing any string conversions, so why introduce them?
If your aim is to display (as a string) the current date and time in a particular time zone, you should just use something like:
Date date = new Date(); // This will use the current time
SimpleDateFormat format = new SimpleDateFormat(...); // Pattern and locale
format.setTimeZone(zone); // The zone you want to display in
String formattedText = format.format(date);
When working with date and time APIs - particularly bad ones like the Java Calendar/Date API - it's very important that you understand exactly what each value in your system represents.

Current Time/Date Code Error

How do I get Current Time as this code is giving (Time-->Thu Jan 01 05:56:27 ACT 1970)??
DateFormat timeFormat = new SimpleDateFormat("HH:mm:ss.SS");
Date time = new Date();
String currentTime=timeFormat.format(time);
time=timeFormat.parse(currentTime);
System.out.println("Time-->"+time);
salesOrder.setOrderTime(time);
Class java.util.Date is not suitable for storing only a time-of-day (hours, minutes, seconds, milliseconds). Class Date is a timestamp, it contains a number of milliseconds since 01-01-1970, 00:00:00 GMT.
Use LocalTime from the Joda Time library for this instead.
Note: What you are doing in your code is first formatting a Date object to a String, and then parsing it back to a Date again, throwing away the day, month, year part. What you end up with is a Date object that's set to a number of hours, minutes, seconds and milliseconds since 01-01-1970, 00:00:00 GMT.
use DateFormat timeFormat = new SimpleDateFormat();
instead of
DateFormat timeFormat = new SimpleDateFormat("HH:MM:ss:SS");
The problem is in formatting. You have not provided the Day,year fieldr, thats why it is acting that way. Or You can use this with proper formatting :
DateFormat timeFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
EDIT:
Try this:
Calendar c = Calendar.getInstance();
c.setTime(time);
System.out.println(c.get(Calendar.YEAR)+ " "+c.get(Calendar.MONTH)+ " "+ c.get(Calendar.DAY_OF_MONTH));
Where time set in Calendar object is time that is not parsed/formatted using simpleDateFormat.
From calendar object, you can get individual month , day , year and use it the way you like, or you can just call c.getTime() to get the Date object.
Your format only contains hours and minutes and seconds. Given just a time of day with no date component, DateFormat.parse() does not fill in the current date; it falls back on the epoch of the system, "time zero", which is January 1, 1970. If you want a date string that can be turned back into a Date object, you need to include the year and month and day as well as the hour.

Unable to get the date in UTC format

I have written two functions - today() and todayUTC() - as:
public static Date today() {
Calendar cal = Calendar.getInstance();
return cal.getTime();
}
public static Date todayUTC() {
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
return cal.getTime();
}
But when I print the results of these functions using:
public void todayTest() {
Date date1 = OOTBFunctions.today();
System.out.println("today: "+date1);
Date dateUTC1 = OOTBFunctions.todayUTC();
System.out.println("todayUTC: "+dateUTC1);
}
I saw that both statements print the same value i.e.
today: Thu Aug 30 14:48:56 PDT 2012
todayUTC: Thu Aug 30 14:48:56 PDT 2012
Can anybody suggest what am I missing in UTC function that I am getting local timezone date.
Java uses the default Locale while printing and that is why you see that behavior. Use code like below to format and print it in the locale/format you want. Remember
When you create a Date object, it is always in UTC.
Display the date in the Locale of the user.
Store the date in UTC.
Code
final SimpleDateFormat sdf = new SimpleDateFormat("the format you want");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
final String utcTime = sdf.format(new Date());
You doesn't need both today() and todayUTC() methods. keep and like below
public static Date nowInUTC()
{
return new Date();
}
You doesn't need to test anything.
Both of your methods will return the same value - a Date object doesn't have any notion of a time zone (unlike a Calendar). A Date just represents an instant in time, stored internally as the number of milliseconds since midnight January 1st 1970, UTC. Effectively, you've got two methods which are equivalent to:
return new Date(System.currentTimeMillis());
Date.toString() always uses the system default time zone.
If you want to maintain a date/time with a time zone, consider just using Calendar. If you want to format a particular instant in time in a time zone, just use SimpleDateFormat having set the time zone.
Ideally, change to use Joda Time instead of Date or Calendar though - it's a much cleaner API.

Categories