Android中的时区问题

时间:2011-10-07 05:23:15

标签: java android timezone

我有时间以毫秒为单位,我在"MM/dd/yyyy HH:mm:ss"格式的应用程序中显示该时间,它工作正常。

问题:如果我在Android设备中更改时区,则在我的应用程序中显示不同的时间可能是因为某些时区计算。我希望在我的数据库中显示与任何时区相同的时间。

我使用以下代码测试时区问题

Locale locale = new Locale("en", "IN");

TimeZone tz = TimeZone.getDefault();
System.out.println("Default timezon id :: " + tz.getID());
tz.setID("Asia/Calcutta");
String timezon = tz.getDisplayName(false, TimeZone.SHORT, locale);
System.out.println("Timezon id :: " + tz.getID() + " Timezon name :: " + timezon);
Calendar cal = Calendar.getInstance(tz, locale);

System.out.println("TImezon :: " + tz);
// "1319084400775" is the milliseconds of 10/20/2011 05:20:00 in MM/dd/yyyy HH:mm:ss format 
Date date = new Date(Long.parseLong("1319084400775"));
System.out.println("Date :: " + date.toGMTString());
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", locale);

System.out.println("Start date :: " + format.format(date));
// "1319084400775" is the milliseconds of 10/20/2011 05:20:00 in MM/dd/yyyy HH:mm:ss format 
cal.setTimeInMillis(Long.parseLong("1319084400775"));

timezon = cal.getTimeZone().getDisplayName(false, TimeZone.SHORT, locale);
System.out.println("Calender's timezon :: " + timezon);
System.out.println("Start date :: yyyy-mm-dd hh:mm:ss " + cal.get(Calendar.YEAR) + "-" + cal.get(Calendar.MONTH) + "-" + cal.get(Calendar.DAY_OF_MONTH) + " " + cal.get(Calendar.HOUR_OF_DAY) + ":" + cal.get(Calendar.MINUTE));
// "1319084700776" is the milliseconds of 10/20/2011 05:25:00 in MM/dd/yyyy HH:mm:ss format 
cal.setTimeInMillis(Long.parseLong("1319084700776"));
System.out.println("End date :: " + cal.getTime());

输出::

如果我为“太平洋/斐济”设置时区;

10-07 17:03:40.392: INFO/System.out(1193): Default timezon id :: Pacific/Fiji
10-07 17:03:40.392: INFO/System.out(1193): Timezon id :: Asia/Calcutta Timezon name :: GMT+05:30
10-07 17:03:40.406: INFO/System.out(1193): TImezon :: org.apache.harmony.luni.internal.util.ZoneInfo@7b42d3a7
10-07 17:03:40.422: INFO/System.out(1193): Date :: 20 Oct 2011 04:20:00 GMT
10-07 17:03:40.442: INFO/System.out(1193): Start date :: 2011-10-20 16:20:00
10-07 17:03:40.442: INFO/System.out(1193): Calender's timezon :: GMT+05:30
10-07 17:03:40.442: INFO/System.out(1193): Start date :: yyyy-mm-dd hh:mm:ss 2011-9-20 16:20
10-07 17:03:40.452: INFO/System.out(1193): End date :: Thu Oct 20 16:25:00 Pacific/Fiji 2011

如果我为“America / Tijuana”设置时区;

10-06 22:05:20.702: INFO/System.out(1193): Default timezon id :: America/Tijuana
10-06 22:05:20.712: INFO/System.out(1193): Timezon id :: Asia/Calcutta Timezon name :: GMT+05:30
10-06 22:05:20.712: INFO/System.out(1193): TImezon :: org.apache.harmony.luni.internal.util.ZoneInfo@1294e658
10-06 22:05:20.733: INFO/System.out(1193): Date :: 20 Oct 2011 04:20:00 GMT
10-06 22:05:20.742: INFO/System.out(1193): Start date :: 2011-10-19 21:20:00
10-06 22:05:20.742: INFO/System.out(1193): Calender's timezon :: GMT+05:30
10-06 22:05:20.752: INFO/System.out(1193): Start date :: yyyy-mm-dd hh:mm:ss 2011-9-19 21:20
10-06 22:05:20.752: INFO/System.out(1193): End date :: Wed Oct 19 21:25:00 America/Tijuana 2011

修改

我有时间在几毫秒内现在我在我的应用程序中以日期格式显示毫秒,但问题是我在设备中更改了时区我根据该时区得到了日期。

3 个答案:

答案 0 :(得分:12)

日期只是世界时刻的瞬间。它没有时区的概念。把它想象成“肯尼迪被杀的时候”。

当您使用SimpleDateFormat显示此时间时,此日期格式具有时区,您可以使用此时区显示此时刻。因此,如果日期格式的时区是中央标准时间,则此时间将显示为12:30。如果时区为UTC,则显示为18:30。

如果您想要以相同的方式显示某个日期,无论时区如何,您只需选择特定时区(例如UTC),并始终显示此时区的日期。因此,在格式化日期之前,您必须在setTimeZone上致电DateFormat

答案 1 :(得分:4)

在标准Java中:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
sdf.setTimeZone(TimeZone.getTimeZone(<your timezone here>);

long millis = <your timestamp here>; //timestamps are not TZ dependent.
Date d = new Date(millis);
String toDisplay = sdf.format(d);

SimpleDateFormat中的时区是您要为每个显示日期使用的固定时区,而不是设备的默认时区。 还要确保数据库中的timestamp列在与Java相同的时间点开始计数(1/1/1970,AKA Unix纪元),并具有相同的精度(毫秒)。

还有另一个android.text.format.DateFormat类,但我没有看到使用它的任何意义。

答案 2 :(得分:3)

我得到如下方法

的解决方案
/**
     * Date time must be in milliseconds  
     * return Time in milliseconds
     */
    public static String getTimeInMilli(Context ctx, String datetime) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(Long.parseLong(datetime));
        //This will return daylight savings offset in milliseconds.You have to Subtract  this milliseconds from calendar
        int dayLightSaving  = cal.get(Calendar.DST_OFFSET);

        cal.setTimeInMillis(cal.getTimeInMillis() - dayLightSaving);

        TimeZone z = cal.getTimeZone();
        int offset = z.getRawOffset();
        int offsetHrs = offset / 1000 / 60 / 60;
        int offsetMins = offset / 1000 / 60 % 60;

        // Subtract offset of your current TimeZone
        cal.add(Calendar.HOUR_OF_DAY, (-offsetHrs));
        cal.add(Calendar.MINUTE, (-offsetMins));

        cal.setTimeZone(TimeZone.getTimeZone("GMT"));

        //add offset of your TimeZone
        cal.add(Calendar.HOUR_OF_DAY, 5);
        cal.add(Calendar.MINUTE, 30);

        return String.valueOf(cal.getTimeInMillis());
    }

现在如果我在设备中更改时区,我的应用程序的日期将保持不变。