3

I am writing an app which has a DatePicker and a TimePicker in the UI. I need to get the date and time set by the user and store in the server.

For example user chose "13 Nov 2015 13:00", and the timezone of my emulator is set as GMT+8, the returned timeInSec in GMT independent of time zone should be "1447390800", but it turns out to be "1447387200", a difference of 1 hour. End up my displayed time received from server also wrong.

Why is it so? Something to do with daylight savings in GMT timezone countries or what have I done wrongly in the code? In my country there is no daylight savings..

Here is my code:

Calendar cal = Calendar.getInstance();
cal.set(mDatePicker.getYear(), mDatePicker.getMonth(), mDatePicker.getDayOfMonth(), mTimePicker.getCurrentHour(), mTimePicker.getCurrentMinute(), 0);
// get time in seconds independent of timezone <- update on 2015/11/14: this is wrong!! 
long timezoneOffset = cal.getTimeZone().getOffset(cal.getTimeInMillis());
long timeInSec = ((cal.getTimeInMillis() + timezoneOffset)/1000);

Update

After checking through the code again, you found it is my TimePicker giving the wrong value.

halfer
  • 19,824
  • 17
  • 99
  • 186
yeeen
  • 4,911
  • 11
  • 52
  • 73

2 Answers2

3

If you want the UTC timestamp you can directly use getTimeInMillis()

public long getTimeInMillis()

Returns: the current time as UTC milliseconds from the epoch.

Reference:
http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#getTimeInMillis()

For example set the calendar date to 13 Nov 2015 13:00 with a GMT+8 timezone:

Calendar calendar = Calendar.getInstance();
calendar.set(2015, Calendar.NOVEMBER, 13, 13, 0, 0);
int timeInSec = calendar.getTimeInMillis() / 1000;

the value of timeInSec is 1447390800

EDIT

What is the output you obtain with this snippet of code?

Calendar calendar = Calendar.getInstance();
calendar.set(2015, Calendar.NOVEMBER, 13, 13, 0, 0);
int offset = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
long utcTimeInMillis = calendar.getTimeInMillis() + offset;

Calendar utcCalendar = Calendar.getInstance(Locale.ENGLISH);
utcCalendar.setTimeInMillis(utcTimeInMillis);

Log.d(TAG, "Time: " + calendar.getTime());
Log.d(TAG, "TimeInMillis: " + calendar.getTimeInMillis());
Log.d(TAG, "DisplayName: " + calendar.getTimeZone().getDisplayName());
Log.d(TAG, "Offset: " + offset);
Log.d(TAG, "UTC Time: " + utcCalendar.getTime());
Log.d(TAG, "UTC TimeInMillis: " + utcTimeInMillis);

This is the result I obtained:

Time: Fri Nov 13 13:00:00 GMT+08:00 2015
TimeInMillis: 1447390800061
DisplayName: Hong Kong Standard Time
Offset: 28800000
UTC Time: Fri Nov 13 21:00:00 GMT+08:00 2015
UTC TimeInMillis: 1447419600061
Mattia Maestrini
  • 32,270
  • 15
  • 87
  • 94
  • cal.getTimeInMillis() is dependent on my timezone. http://stackoverflow.com/questions/13083243/calendar-gettimeinmillis-is-timezone-dependent?rq=1 I purposely minus the timezone offset for that reason. If i store in server this value, the retrieved value is also wrong. – yeeen Nov 11 '15 at 01:05
  • @yeeen I just updated my answer, what is the value you obtained with that code? – Mattia Maestrini Nov 11 '15 at 09:28
  • Same as mine when round off to seconds. I found that is my TimePicker which is one giving me the wrong time! I chose 13:00 why is it when i do getCurrentHour() and getCurrentMinute(), it gives me 4 and 0 instead? I tried other date and time as well, it is always 9 hrs earlier than my selected time! – yeeen Nov 11 '15 at 13:58
  • @yeeen It is zero with your current date. But it's incorrect to not consider `DST_OFFSET`. For example if you have 13 June 2015 with GTM+1 it will be 3600000. – Mattia Maestrini Nov 11 '15 at 14:07
  • Ok ya, need to consider support for other timezone as well. But my problem is still not solved. Now seems to be TimePicker issue?? :( – yeeen Nov 11 '15 at 14:09
  • Without any other information is not possible to help you. Show us how you declare and you use the `TimePicker`. – Mattia Maestrini Nov 11 '15 at 14:14
  • As request, i have attached the file that creates the date and time dialog in the question. My TimePicker is a bit special cos i need to use 15 mins interval, but it shldn't affect the timezone anyway right? Strange... – yeeen Nov 11 '15 at 15:07
  • 1
    The value is 9 hours earlier because the display values and real values is different. You set the min value to 0 and the displayed values is 9. This [answer](http://stackoverflow.com/a/33184812/2837959) explains the difference between display values and real values in `NumberPicker`. To quickly solve the issue you can add 9 to the `getCurrentHour()` and multiply `getCurrentMinute()` by 15. – Mattia Maestrini Nov 11 '15 at 15:12
  • Wow... I see! Thanks a lot – yeeen Nov 11 '15 at 23:13
  • For ppl reading this, do note that there is a misunderstanding that getTimeInMillis() returns time dependent on timezone. It shld be independent. – yeeen Nov 14 '15 at 15:38
1

(Posted on behalf of the question author).

The problem was because of the TimePicker.

Calendar.currentTimeMillis() actually gives time independent of timezone (i.e. UTC). This link (Java: Timezone why different timezone give same value in millisec) is so misleading! This should be what you should be looking at: http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#getTimeInMillis()

So I should be just doing this:

Calendar cal = Calendar.getInstance();
cal.set(mDatePicker.getYear(), mDatePicker.getMonth(), mDatePicker.getDayOfMonth(), mTimePicker.getCurrentHour(), mTimePicker.getCurrentMinute(), 0);
long timeInSec = (cal.getTimeInMillis()/1000);
halfer
  • 19,824
  • 17
  • 99
  • 186