12 个解决方案
#1
.net 生成时间戳好像是以公元元年来计算的就是以 0001-01-01 00:00:00
java 应该是以1970-01-01 00:00:00
java 中(2011-06-24 17:27:34)减(1970-01-01 00:00:00)得到的毫秒数应该就是那个13位的数
这个你得想办法计算一下了
java 应该是以1970-01-01 00:00:00
java 中(2011-06-24 17:27:34)减(1970-01-01 00:00:00)得到的毫秒数应该就是那个13位的数
这个你得想办法计算一下了
#2
路过的
#3
public static final long BASETIME = (long)(1970*365 + (25*20-8) - 19 + 5) * 24 * 60 * 60 * 1000;
public String convert(long oldtime) {
long newtime = BASETIME + oldtime;
return newtime + "0000";
}
#4
我这样子调用了以后就成了2012-6-25 9:48:11 实际时间是2011-06-25 17:48:11
(long)(1970*365 + (25*20-8) - 19 + 5) * 24 * 60 * 60 * 1000;
这一串数字代表什么意思呢?
请继续指教啊~
#5
绝对没有那么简单,这涉及很复杂的历法转换。
在 Java 中公元纪年是采用格里高利历的,这个历法的起始时间是 1582 年 10 月 15 日,也就是说在这个日期之前的格里高利历纪年是不存在的。
而且 1582 年 10 月 4 日这一天,罗马教宗就规定下一天为 1582 年 10 月 15 日,这一天也是格里高利历的起始日,同时修改的包括闰年规则。
要换算成公元 1 年 1 月 1 日 0 时至今的毫秒数并不是加加减减那么简单。
#6
1582 年 10 月 5 日 ~ 1582 年 10 月 14 日,这几天在历法是不存在的 10 天。
#7
关于格里高利历的确实在*上看了一下。 如火龙果说的。
弱弱问一下,时间戳一定要依赖某种历法吗? 只要能精确地唯一地表示某一时候不就可以吗?
弱弱问一下,时间戳一定要依赖某种历法吗? 只要能精确地唯一地表示某一时候不就可以吗?
#8
根据 MSDN 中关于 DateTime#ticks 的文档
这个时间戳表示的是公元 0001-01-01 00:00:00.00000000 至今的百纳秒时间间隔。
这里的公元使用的是儒略历,而 Java 中使用的是格里高利历,因此换算时需要处理格里高利历与儒略历之间的差值。
这个差值很复杂的,详见 wikipedia 上的说明:
http://zh.wikipedia.org/wiki/%E6%A0%BC%E9%87%8C%E9%AB%98%E5%88%A9%E5%8E%86#.E6.A0.BC.E9.87.8C.E6.9B.86.E6.97.A5.E6.9C.9F.E8.88.87.E5.84.92.E7.95.A5.E6.9B.86.E6.97.A5.E6.9C.9F.E7.9A.84.E5.B7.AE.E8.B7.9D
这个时间戳表示的是公元 0001-01-01 00:00:00.00000000 至今的百纳秒时间间隔。
这里的公元使用的是儒略历,而 Java 中使用的是格里高利历,因此换算时需要处理格里高利历与儒略历之间的差值。
这个差值很复杂的,详见 wikipedia 上的说明:
http://zh.wikipedia.org/wiki/%E6%A0%BC%E9%87%8C%E9%AB%98%E5%88%A9%E5%8E%86#.E6.A0.BC.E9.87.8C.E6.9B.86.E6.97.A5.E6.9C.9F.E8.88.87.E5.84.92.E7.95.A5.E6.9B.86.E6.97.A5.E6.9C.9F.E7.9A.84.E5.B7.AE.E8.B7.9D
#9
看时间差了1年,这是因为我没用过.net,所以不清楚.net的公元元年的含义是公元1年1月1日,还以为是公元0年1月1日,不过这也正说明我的计算公式原理是正确的
public static final long BASETIME = (long)(1970*365 + (25*20-8) - 19 + 5) * 24 * 60 * 60 * 1000;
改为
public static final long BASETIME = (long)(1969*365 + (25*20-8) - 19 + 5) * 24 * 60 * 60 * 1000;
修正了这1年时间后还差8小时整,我估计是因为时区的时差,.net取时间和Java取时间时所默认的时区不同。LZ你检查一下。
5楼的,所谓格里高利历法跟这个转换有什么关系呢,Java就算用格里高利历法,但它取时间只从1970年1月1日算起,又不用往前推,500年前少了多少天完全影响不到它的取时。重要的是.net算到公元元年它是怎么算的。LZ的检查恰恰证明.net的时间计算跟我应用的原理一模一样。
#10
(long)(1970*365 + (25*20-8) - 19 + 5) * 24 * 60 * 60 * 1000;
公元历法每年365天,有闰2月的年份会多1天
闰2月的规律是这样的:
4年一闰,100年不闰,400年又闰。
举例来说,1888,1892,1896都是闰年,1900年逢百年不闰,1904,1908......1996都是闰年,2000年由于逢400年,也是闰年。未来2100年不闰。
long BASETIME = (long)(1969*365 + (25*20-8) - 19 + 5) * 24 * 60 * 60 * 1000; 就是对应这个规则设计的,1969年每年365天,后面20×20-8-19+5是计算自公元元年至1970年的闰年数,每个闰年加一天。
24 小时/天
60 分钟/小时
60 秒/分钟
1000 毫秒/秒
BASETIME代表从公元元年1月1日至1970.01.01的毫秒数
Java取得的时间oldtime是毫秒,所以可以跟BASETIME相加
.net取的时间是100个毫微秒为1单位,所以在后面再加4个0
公元历法每年365天,有闰2月的年份会多1天
闰2月的规律是这样的:
4年一闰,100年不闰,400年又闰。
举例来说,1888,1892,1896都是闰年,1900年逢百年不闰,1904,1908......1996都是闰年,2000年由于逢400年,也是闰年。未来2100年不闰。
long BASETIME = (long)(1969*365 + (25*20-8) - 19 + 5) * 24 * 60 * 60 * 1000; 就是对应这个规则设计的,1969年每年365天,后面20×20-8-19+5是计算自公元元年至1970年的闰年数,每个闰年加一天。
24 小时/天
60 分钟/小时
60 秒/分钟
1000 毫秒/秒
BASETIME代表从公元元年1月1日至1970.01.01的毫秒数
Java取得的时间oldtime是毫秒,所以可以跟BASETIME相加
.net取的时间是100个毫微秒为1单位,所以在后面再加4个0
#11
要考虑时区。
public class Jdate2CshapeTicks {
private static final long TICKS_AT_EPOCH = 621355968000000000L;
private static final long TICKS_PER_MILLISECOND = 10000;
private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
private static TimeZone timeZone = TimeZone.getDefault();
/**
* 将C#的ticks值转换成Java的Date对象
* @param ticks
* @return
*/
public static Date fromDnetTicksToJdate(long ticks){
Calendar calendar = Calendar.getInstance(timeZone);
calendar.setTimeInMillis((ticks - TICKS_AT_EPOCH) / TICKS_PER_MILLISECOND);
calendar.setTimeInMillis(calendar.getTimeInMillis() - calendar.getTimeZone().getRawOffset());
return calendar.getTime();
}
/**
* 将日期的字符串值转换成C#的ticks值
* @param time
* @return
*/
public static long getCShapeTicks(String time){
long result = -1;
Date date = null;
try {
date = sdf.parse(time);
Calendar calendar = Calendar.getInstance(timeZone);
calendar.setTime(date);
return (calendar.getTimeInMillis() + calendar.getTimeZone().getRawOffset()) * TICKS_PER_MILLISECOND + TICKS_AT_EPOCH;
} catch (Exception e) {
}
return result;
}
/**
* 将Java日期对象转换成C#的ticks值
* @param jDate
* @return
*/
public static long getCShapeTicks(Date jDate){
long result = -1;
try {
Calendar calendar = Calendar.getInstance(timeZone);
calendar.setTime(jDate);
return (calendar.getTimeInMillis() + calendar.getTimeZone().getRawOffset()) * TICKS_PER_MILLISECOND + TICKS_AT_EPOCH;
} catch (Exception e) {
}
return result;
}
}
#12
mark一下
#1
.net 生成时间戳好像是以公元元年来计算的就是以 0001-01-01 00:00:00
java 应该是以1970-01-01 00:00:00
java 中(2011-06-24 17:27:34)减(1970-01-01 00:00:00)得到的毫秒数应该就是那个13位的数
这个你得想办法计算一下了
java 应该是以1970-01-01 00:00:00
java 中(2011-06-24 17:27:34)减(1970-01-01 00:00:00)得到的毫秒数应该就是那个13位的数
这个你得想办法计算一下了
#2
路过的
#3
public static final long BASETIME = (long)(1970*365 + (25*20-8) - 19 + 5) * 24 * 60 * 60 * 1000;
public String convert(long oldtime) {
long newtime = BASETIME + oldtime;
return newtime + "0000";
}
#4
我这样子调用了以后就成了2012-6-25 9:48:11 实际时间是2011-06-25 17:48:11
(long)(1970*365 + (25*20-8) - 19 + 5) * 24 * 60 * 60 * 1000;
这一串数字代表什么意思呢?
请继续指教啊~
#5
绝对没有那么简单,这涉及很复杂的历法转换。
在 Java 中公元纪年是采用格里高利历的,这个历法的起始时间是 1582 年 10 月 15 日,也就是说在这个日期之前的格里高利历纪年是不存在的。
而且 1582 年 10 月 4 日这一天,罗马教宗就规定下一天为 1582 年 10 月 15 日,这一天也是格里高利历的起始日,同时修改的包括闰年规则。
要换算成公元 1 年 1 月 1 日 0 时至今的毫秒数并不是加加减减那么简单。
#6
1582 年 10 月 5 日 ~ 1582 年 10 月 14 日,这几天在历法是不存在的 10 天。
#7
关于格里高利历的确实在*上看了一下。 如火龙果说的。
弱弱问一下,时间戳一定要依赖某种历法吗? 只要能精确地唯一地表示某一时候不就可以吗?
弱弱问一下,时间戳一定要依赖某种历法吗? 只要能精确地唯一地表示某一时候不就可以吗?
#8
根据 MSDN 中关于 DateTime#ticks 的文档
这个时间戳表示的是公元 0001-01-01 00:00:00.00000000 至今的百纳秒时间间隔。
这里的公元使用的是儒略历,而 Java 中使用的是格里高利历,因此换算时需要处理格里高利历与儒略历之间的差值。
这个差值很复杂的,详见 wikipedia 上的说明:
http://zh.wikipedia.org/wiki/%E6%A0%BC%E9%87%8C%E9%AB%98%E5%88%A9%E5%8E%86#.E6.A0.BC.E9.87.8C.E6.9B.86.E6.97.A5.E6.9C.9F.E8.88.87.E5.84.92.E7.95.A5.E6.9B.86.E6.97.A5.E6.9C.9F.E7.9A.84.E5.B7.AE.E8.B7.9D
这个时间戳表示的是公元 0001-01-01 00:00:00.00000000 至今的百纳秒时间间隔。
这里的公元使用的是儒略历,而 Java 中使用的是格里高利历,因此换算时需要处理格里高利历与儒略历之间的差值。
这个差值很复杂的,详见 wikipedia 上的说明:
http://zh.wikipedia.org/wiki/%E6%A0%BC%E9%87%8C%E9%AB%98%E5%88%A9%E5%8E%86#.E6.A0.BC.E9.87.8C.E6.9B.86.E6.97.A5.E6.9C.9F.E8.88.87.E5.84.92.E7.95.A5.E6.9B.86.E6.97.A5.E6.9C.9F.E7.9A.84.E5.B7.AE.E8.B7.9D
#9
看时间差了1年,这是因为我没用过.net,所以不清楚.net的公元元年的含义是公元1年1月1日,还以为是公元0年1月1日,不过这也正说明我的计算公式原理是正确的
public static final long BASETIME = (long)(1970*365 + (25*20-8) - 19 + 5) * 24 * 60 * 60 * 1000;
改为
public static final long BASETIME = (long)(1969*365 + (25*20-8) - 19 + 5) * 24 * 60 * 60 * 1000;
修正了这1年时间后还差8小时整,我估计是因为时区的时差,.net取时间和Java取时间时所默认的时区不同。LZ你检查一下。
5楼的,所谓格里高利历法跟这个转换有什么关系呢,Java就算用格里高利历法,但它取时间只从1970年1月1日算起,又不用往前推,500年前少了多少天完全影响不到它的取时。重要的是.net算到公元元年它是怎么算的。LZ的检查恰恰证明.net的时间计算跟我应用的原理一模一样。
#10
(long)(1970*365 + (25*20-8) - 19 + 5) * 24 * 60 * 60 * 1000;
公元历法每年365天,有闰2月的年份会多1天
闰2月的规律是这样的:
4年一闰,100年不闰,400年又闰。
举例来说,1888,1892,1896都是闰年,1900年逢百年不闰,1904,1908......1996都是闰年,2000年由于逢400年,也是闰年。未来2100年不闰。
long BASETIME = (long)(1969*365 + (25*20-8) - 19 + 5) * 24 * 60 * 60 * 1000; 就是对应这个规则设计的,1969年每年365天,后面20×20-8-19+5是计算自公元元年至1970年的闰年数,每个闰年加一天。
24 小时/天
60 分钟/小时
60 秒/分钟
1000 毫秒/秒
BASETIME代表从公元元年1月1日至1970.01.01的毫秒数
Java取得的时间oldtime是毫秒,所以可以跟BASETIME相加
.net取的时间是100个毫微秒为1单位,所以在后面再加4个0
公元历法每年365天,有闰2月的年份会多1天
闰2月的规律是这样的:
4年一闰,100年不闰,400年又闰。
举例来说,1888,1892,1896都是闰年,1900年逢百年不闰,1904,1908......1996都是闰年,2000年由于逢400年,也是闰年。未来2100年不闰。
long BASETIME = (long)(1969*365 + (25*20-8) - 19 + 5) * 24 * 60 * 60 * 1000; 就是对应这个规则设计的,1969年每年365天,后面20×20-8-19+5是计算自公元元年至1970年的闰年数,每个闰年加一天。
24 小时/天
60 分钟/小时
60 秒/分钟
1000 毫秒/秒
BASETIME代表从公元元年1月1日至1970.01.01的毫秒数
Java取得的时间oldtime是毫秒,所以可以跟BASETIME相加
.net取的时间是100个毫微秒为1单位,所以在后面再加4个0
#11
要考虑时区。
public class Jdate2CshapeTicks {
private static final long TICKS_AT_EPOCH = 621355968000000000L;
private static final long TICKS_PER_MILLISECOND = 10000;
private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
private static TimeZone timeZone = TimeZone.getDefault();
/**
* 将C#的ticks值转换成Java的Date对象
* @param ticks
* @return
*/
public static Date fromDnetTicksToJdate(long ticks){
Calendar calendar = Calendar.getInstance(timeZone);
calendar.setTimeInMillis((ticks - TICKS_AT_EPOCH) / TICKS_PER_MILLISECOND);
calendar.setTimeInMillis(calendar.getTimeInMillis() - calendar.getTimeZone().getRawOffset());
return calendar.getTime();
}
/**
* 将日期的字符串值转换成C#的ticks值
* @param time
* @return
*/
public static long getCShapeTicks(String time){
long result = -1;
Date date = null;
try {
date = sdf.parse(time);
Calendar calendar = Calendar.getInstance(timeZone);
calendar.setTime(date);
return (calendar.getTimeInMillis() + calendar.getTimeZone().getRawOffset()) * TICKS_PER_MILLISECOND + TICKS_AT_EPOCH;
} catch (Exception e) {
}
return result;
}
/**
* 将Java日期对象转换成C#的ticks值
* @param jDate
* @return
*/
public static long getCShapeTicks(Date jDate){
long result = -1;
try {
Calendar calendar = Calendar.getInstance(timeZone);
calendar.setTime(jDate);
return (calendar.getTimeInMillis() + calendar.getTimeZone().getRawOffset()) * TICKS_PER_MILLISECOND + TICKS_AT_EPOCH;
} catch (Exception e) {
}
return result;
}
}
#12
mark一下