我有一毫秒,因为本地历元时间戳,我想转换成毫秒,因为-UTC-时代时间戳。从文档快速浏览它看起来像这样的事情会工作:将本地时间戳UTC时间戳在Java中
int offset = TimeZone.getDefault().getRawOffset();
long newTime = oldTime - offset;
有没有更好的方式来做到这一点?
我有一毫秒,因为本地历元时间戳,我想转换成毫秒,因为-UTC-时代时间戳。从文档快速浏览它看起来像这样的事情会工作:将本地时间戳UTC时间戳在Java中
int offset = TimeZone.getDefault().getRawOffset();
long newTime = oldTime - offset;
有没有更好的方式来做到这一点?
使用Calendar
得到什么补偿是在当地大纪元,然后添加到本地划时代时间戳。
public static long getLocalToUtcDelta() {
Calendar local = Calendar.getInstance();
local.clear();
local.set(1970, Calendar.JANUARY, 1, 0, 0, 0);
return local.getTimeInMillis();
}
public static long converLocalTimeToUtcTime(long timeSinceLocalEpoch) {
return timeSinceLocalEpoch + getLocalToUtcDelta();
}
没有,那肯定是行不通的 - 它没有考虑DST考虑。你不能只用getOffset(oldTime)
无论是作为DST可能在两者之间改变......
你可以使用getOffset(oldTime)
在时间戳获得初始猜测,然后检查getOffset(utcTime)
,看他们是否是相同的或不。基本上它变得有趣。
Joda Time应该支持这种使用DateTimeZone.getOffsetFromLocal
但是这slightly broken(IMO)周围DST过渡。
一切真的取决于你所说的“因为当地毫秒为单位”的东西。如果你真的意味着自1970年当地经过毫秒,你可以只发现在该日期的偏移量,并应用不管。通常情况下(IME)“本地”millis值并不完全意味着这个数字 - 它意味着“以毫秒为单位获得特定日期和时间的毫秒数(例如2010年4月9日18:06 pm),但是就一个不同的时区“。换句话说,它可以表示基于DST转换的模糊或不可能的日期/时间组合。
但我认为你可以使用'的getOffset(0L)'所有的事情就是时间差那时候,在时代的开始 - 我希望,1月1日DST转换不会发生。 – 2010-04-09 17:09:53
可悲的是,这似乎是做到这一点的最好办法:
public static Date convertLocalTimestamp(long millis)
{
TimeZone tz = TimeZone.getDefault();
Calendar c = Calendar.getInstance(tz);
long localMillis = millis;
int offset, time;
c.set(1970, Calendar.JANUARY, 1, 0, 0, 0);
// Add milliseconds
while (localMillis > Integer.MAX_VALUE)
{
c.add(Calendar.MILLISECOND, Integer.MAX_VALUE);
localMillis -= Integer.MAX_VALUE;
}
c.add(Calendar.MILLISECOND, (int)localMillis);
// Stupidly, the Calendar will give us the wrong result if we use getTime() directly.
// Instead, we calculate the offset and do the math ourselves.
time = c.get(Calendar.MILLISECOND);
time += c.get(Calendar.SECOND) * 1000;
time += c.get(Calendar.MINUTE) * 60 * 1000;
time += c.get(Calendar.HOUR_OF_DAY) * 60 * 60 * 1000;
offset = tz.getOffset(c.get(Calendar.ERA), c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH), c.get(Calendar.DAY_OF_WEEK), time);
return new Date(millis - offset);
}
(我知道这是好几个月过去后的日期,但它是非常有用的,当解决问题Android上的短信工作Dave的答案是错的)
使用约达时间它会是这样:。
DateTime dt = new DateTime(year, month, day, hour, minute, 0, 0, DateTimeZone.forID("local");
dt.getMillis();
编辑:对不起,这是正确的版本:
DateTime dt = new DateTime(timestamp, DateTimeZone.forID("local");
dt.getMillis();
实际上,克里斯Lercher击中了要害,但他只在很短的评论做到了,所以我想它扩大。
假设有两个秒表;一个是1970年1月1日UTC是当地时间的地方,另一个秒表是本地的(假设它在纽约,UTC后5小时)。在UTC午夜,1970年1月1日,UTC秒表启动。 5小时后,您的本地秒表开始启动。这两个秒表时间相差一定数量,仅由当地UTC时间当地午夜 1970年1月1日之间的差异确定。从那时起,任何夏令时的诡计都不会影响这些秒表之间的差异。因此,您的目前时间或您的转换的任何DST更正都是无关紧要的。所有你需要的是你的本地秒表开始于1970年1月1日多少时间。
正如克里斯指出,这仅仅是:的getOffset(0L),所以:
int offset = TimeZone.getDefault().getOffset(0L);
long newTime = oldTime - offset;
...应该能正常运行。 然而 ....
为了帮助真正掌握这一点,请注意这一点:“01”中的getOffset()是自UTC时代毫秒(这是唯一真正划时代)。因此,您的偏移量变量将在UTC的午夜时间(即,在纽约时间19/19/19/19:00)具有偏移秒数。如果当地时间在本地午夜之前的最后几小时切换到/从夏令时开始,那么getOffset(0L)将不正确。你需要知道你的夏令时状态是在当地午夜,而不是UTC的午夜。
如果发生这种情况,任何地方(即1970年1月1日当地午夜和UTC午夜之间的任何DST时间段发生变化),我会感到惊讶。然而,只是为了好玩,便宜的破解,以帮助防止这种情况将是检查是否抵消了这些小时更换:
// Offset at UTC midnight
int offset = TimeZone.getDefault().getOffset(0L);
long newTime = oldTime - offset;
// Offset at Local midnight
int localMidnightOffset = TimeZone.getDefault().getOffset(-offset);
这里,localMidnightOffset会是怎样的时区偏移是在一个时间偏移处的毫秒后UTC在1970年的午夜。如果没有发生DST变化,那么localMidnightOffset将等于偏移量,然后就完成了。如果某些DST变化做发生,那么你可能不得不四处搜寻...可能继续做一个
localMidnightOffset = TimeZone.getDefault().getOffset(-localMidnightOffset)
,直到它停止改变......希望你不要陷入死循环。我很想知道是否有人有保证的融合解决方案。
有点让你希望世界是平坦的,是吧?
我在SO上看过一段时间的最佳答案 – paz 2013-05-31 17:56:08
static final long localTimeZoneoffset = TimeZone.getDefault().getOffset(0L);
static final long dstOffset = TimeZone.getDefault().getDSTSavings();
long offsetOftime = TimeZone.getDefault().getOffset(time.getTime());
long timeinmilli = 0L;
if(offsetOftime != localTimeZoneoffset)
timeinmilli = time.getTime()+localTimeZoneoffset+dstOffset;
else
timeinmilli = time.getTime()+localTimeZoneoffset;
return new Timestamp(timeinmilli);
这对我来说转换为UTC。
可能这可以帮助你我尝试这种方式。请评论我是否有任何最佳和优化方式将本地时间转换为UTC时间戳。
String mDate= "Jul 21,2016 1:23 PM";
String mDateFormat =""MMM d,yyyy h:mm a";
电话:getConvertedTimeToUTC(mDate,mDateFormat);
public String getConvertedTimeToUTC(String ourDate, String mDateFormat) {
try {
SimpleDateFormat fmt = new SimpleDateFormat(mDateFormat);
fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
Date value = fmt.parse(ourDate);
if (value != null)
return String.valueOf(value.getTime()/1000);
else
return null;
} catch (Exception e) {
ourDate = "00-00-0000 00:00";
}
return ourDate;
}
下面是结果:(Ref : check conversion)
Result 1469107380
GMT: Thu, 21 Jul 2016 13:23:00 GMT
Your time zone: Thursday 21 July 2016 06:53:00 PM IST GMT+5:30
这并没有考虑到DST。 – 2010-08-26 06:02:05
@Quartz - 它不必,因为我们正在处理来自Epoch的三角洲。你有一个例子(区域和timeSinceLocalEpoch)哪里失败? – leedm777 2010-09-05 20:25:18