我目前正在开发一个应用程序,根据用户的位置(经度和纬度,通常从GPS获取)和时间显示太阳系中的行星。这些行星(据我所知,这不是我的原始代码)依赖于UTC时间戳,因此如果用户在GMT(也称为UTC)时区,行星位置看起来正常。
但是,随着用户进一步走向世界各地,特别是中国和美国,行星的位置会出现错误(最明显的是太阳 - 忽略它是一颗恒星)。我似乎没有正确传递时间到行星位置计算中,而且我不知道原因。
我已经发布了各种版本,但目前没有一个有效的,而且几乎不可能判断某个版本是否有效,直到我发布并收到电子邮件告诉我错了。我们认为这可能是GSM/CDMA冲突,但似乎不是这样。
以下是创建具有GMT时间的日历的原始代码:
public static Calendar convertToGmt(Calendar cal)
{
Date date = cal.getTime();
TimeZone tz = cal.getTimeZone();
//log.debug("input calendar has date [" + date + "]");
//Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
long msFromEpochGmt = date.getTime();
//gives you the current offset in ms from GMT at the current date
int offsetFromUTC = tz.getOffset(msFromEpochGmt);
//log.debug("offset is " + offsetFromUTC);
//create a new calendar in GMT timezone, set to this date and add the offset
Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.setTime(date);
gmtCal.add(Calendar.MILLISECOND, offsetFromUTC);
//log.debug("Created GMT cal with date [" + gmtCal.getTime() + "]");
return gmtCal;
}
这句话后来被改为:
public static Calendar convertToGmt(Calendar cal)
{
Calendar gmtCal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
long time = cal.getTimeInMillis();
long offset = cal.getTimeZone().getRawOffset();
gmtCal.setTimeInMillis(time - offset);
return gmtCal;
}
最新版本:
public static Calendar convertToGmt(Calendar cal)
{
TimeZone timezone = TimeZone.getDefault();
TimeZone utcTimeZone = TimeZone.getTimeZone("UTC");
int currentGMTOffset = timezone.getOffset(cal.getTimeInMillis());
int gmtOffset = utcTimeZone.getOffset(cal.getTimeInMillis());
cal.setTimeInMillis(cal.getTimeInMillis() + (gmtOffset - currentGMTOffset));
return cal;
}
前两个版本中传回了一个Calendar实例,而第三个版本则为了优化而仅更新其静态实例。今天早上我在琢磨,也许可以使用System.currentTimeInMillis,即:
private static Calendar utc = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
private static Calendar cal = Calendar.getInstance();
public static void convertToGmt()
{
cal.setTimeInMillis(System.currentTimeMillis());
utc.setTimeInMillis(cal.getTimeInMillis());
}
但我不确定这是否有任何区别。
我真的对此感到非常困惑 - 有人可以向我解释一下我错在哪里或者我应该如何解决这个问题吗?我希望几双其他的眼睛能够帮助我! :)
Calendar gmtCal = new GregorianCalendar(TimeZone.getTimeZone("GMT")); return gmtCal;
但我们仍然有用户报告位置不正确,由于日期/时间可以在手机设置中进行配置,因此我们认为时区差异可能会影响返回值。 - batterj2