Java Android中的时区问题

Java Android中的时区问题,java,android,timezone,Java,Android,Timezone,我有以毫秒为单位的时间,我正在应用程序中以格式显示该时间,格式为MM/dd/yyyy HH:MM:ss,它工作正常 问题:如果我在android设备中更改时区,应用程序中显示的时间可能会不同,这可能是因为某些时区计算。我希望在数据库中显示的时间与在任何时区中显示的时间相同 我正在使用下面的代码测试时区问题 Locale locale = new Locale("en", "IN"); TimeZone tz = TimeZone.getDefault(); System.out.println

我有以毫秒为单位的时间,我正在应用程序中以
格式显示该时间,格式为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
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
如果我为“美国/提华纳”设置时区

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
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
编辑


我有以毫秒为单位的时间,现在我在应用程序中以日期格式显示毫秒,但问题是当我在设备中更改时区时,我会根据该时区获取日期。日期只是世界时间的一个瞬间。它没有时区的概念。把它想象成“肯尼迪遇害时”

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

如果希望某个日期以相同的方式显示,而不考虑时区,则只需选择特定的时区(例如UTC),并始终使用此时区显示日期。因此,在格式化日期之前,必须在
DateFormat
上调用
setTimeZone

在标准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 sdf=新的SimpleDateFormat(“yyyy-MM-dd-HH:MM”);
setTimeZone(TimeZone.getTimeZone();
long millis=;//时间戳不依赖于TZ。
日期d=新日期(毫秒);
字符串toDisplay=sdf.format(d);
SimpleDataFormat
中的时区是您希望用于每个显示日期的固定时区,而不是设备的默认时区。 还要确保数据库中的timestamp列开始计数的时间点与Java(1/1/1970,又名Unix历元)相同,并且具有相同的精度(毫秒)


还有另一个android.text.format.DateFormat类,但我看不出使用它有什么意义。

我得到了如下方法的解决方案

/**
     * 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());
    }

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

您可以添加(cal.get(Calendar.MONTH)+1)吗在打印行中?仍然不清楚您的查询是关于什么的?@jazz当我更改时区时,您可以看到输出输出不同,我不想要,这意味着我想要与输入相同的日期和时间。我遇到了问题,我从服务器检索到了一个时间,需要在设备时区中显示,它可以动态变化。我使用了新的SimpleDataForm在(“HH:mm”,Locale.getDefault());但当时区发生更改且应用程序已启动时,它的格式不正确。因此,每次在格式化之前,我都会使用实例将时区设置为
HOUR\u MINUTE\u FORMAT=new SimpleDateFormat(“HH:mm”,Locale.getDefault());FORMAT.setTimeZone(timezone.getDefault());
SimpleDataFormat使用时区。我检查了您的方式,但没有解决我的问题。它必须工作。您必须设置固定时区(始终不变)。例如,要在印度显示日期,请使用India TZ。当设备TZ更改时,输出应相同。是的,它正在工作,但如果我要使用日历,那么如何解决此问题使用
Calendar.getInstance()
获取一个
日历实例。但是如果我想使用日历,那么我该如何解决这个问题?请帮助我日历是一个日期的包装器。调用getTime(),你就会得到一个日期。我只在他们把我从数小时的疯狂中解救出来时表示感谢。这就是其中之一;)非常感谢。