Java毫秒(年)
我正在用Java使用毫秒进行一些日期计算,并注意到以下问题:Java毫秒(年),java,Java,我正在用Java使用毫秒进行一些日期计算,并注意到以下问题: private static final int MILLIS_IN_SECOND = 1000; private static final int SECONDS_IN_MINUTE = 60; private static final int MINUTES_IN_HOUR = 60; private static final int HOURS_IN_DAY = 24; private stati
private static final int MILLIS_IN_SECOND = 1000;
private static final int SECONDS_IN_MINUTE = 60;
private static final int MINUTES_IN_HOUR = 60;
private static final int HOURS_IN_DAY = 24;
private static final int DAYS_IN_YEAR = 365; //I know this value is more like 365.24...
private static final long MILLISECONDS_IN_YEAR = MILLIS_IN_SECOND * SECONDS_IN_MINUTE * MINUTES_IN_HOUR * HOURS_IN_DAY * DAYS_IN_YEAR;
System.out.println(MILLISECONDS_IN_YEAR); //Returns 1471228928
我知道那一年大约是31556952000毫秒,所以我的乘法不知怎么的就错了
有人能指出我做错了什么吗?我应该用长的吗?你需要长的。国际贸易总额约为20亿美元
private static final long MILLISECONDS_IN_YEAR = MILLIS_IN_SECOND * ...
右侧的所有操作数都是int
s,因此乘法是用32位有符号整数完成的,这会溢出。将第一个值转换为long
,您将获得预期值
private static final long MILLISECONDS_IN_YEAR = (long)MILLIS_IN_SECOND * ...
您正在溢出
int
类型。在Java中,对两个int
s执行基本算术运算的结果是int
。操作数的类型决定了这一点,而不是结果变量的类型。尝试:
private static final int MILLIS_IN_SECOND = 1000;
private static final int SECONDS_IN_MINUTE = 60;
private static final int MINUTES_IN_HOUR = 60;
private static final int HOURS_IN_DAY = 24;
private static final int DAYS_IN_YEAR = 365; //I know this value is more like 365.24...
private static final long MILLISECONDS_IN_YEAR = (long) MILLIS_IN_SECOND * SECONDS_IN_MINUTE * MINUTES_IN_HOUR * HOURS_IN_DAY * DAYS_IN_YEAR;
我应该用长的吗
对。问题是,由于milliss\u IN__SECOND
等都是int
s,当你将它们相乘时,你会得到int
。您正在将int
转换为long
,但只有在int
乘法已经导致错误答案之后
要解决此问题,您可以将第一个强制转换为long
:
private static final long MILLISECONDS_IN_YEAR =
(long)MILLIS_IN_SECOND * SECONDS_IN_MINUTE * MINUTES_IN_HOUR
* HOURS_IN_DAY * DAYS_IN_YEAR;
试试这个
int MILLIS_IN_SECOND = 1000;
int SECONDS_IN_MINUTE = 60;
int MINUTES_IN_HOUR = 60;
int HOURS_IN_DAY = 24;
int DAYS_IN_YEAR = 365;
long MILLISECONDS_IN_YEAR = (long) MILLIS_IN_SECOND * SECONDS_IN_MINUTE * MINUTES_IN_HOUR * HOURS_IN_DAY * DAYS_IN_YEAR;
System.out.println(MILLISECONDS_IN_YEAR); // Returns 31536000000
虽然其他人已经指出,但您也可以尝试解决问题:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, year);
int daysInYear = calendar.getActualMaximum(Calendar.DAY_OF_YEAR);
System.out.println(TimeUnit.DAYS.toMillis(daysInYear));
要解决此问题,您可以将字母L放在第一个字母之后:例如1000L
如果使用android,我建议: tl;博士 您使用的
int
与long
()是导致号码完全错误的原因,1471228928
是正确的。而且,你们的问题提出了太阳年和日历年的问题
我知道1年=31556952000毫秒
不,那将是一个太阳年的长度,而不是一个日历年。日历年为31536000000毫秒
现代java.time类和ChronoUnit
可以计算日历年数
Year y = Year.now( // Determine the year of the current date (today).
ZoneId.of( "America/Montreal" ) // Determining the year means determining the current date. And determining a date requires a time zone. For any given moment, the date varies around the globe by zone.
) ; // Returns a `Year` object.
long millisInYear =
ChronoUnit.MILLIS.between(
y.atDay( 1 ) // Get the first of the year. Returns a `LocalDate`.
.atStartOfDay( // Determine the first moment of the day. Not always 00:00:00 because of anomalies such as Daylight Saving Time (DST).
ZoneId.of( "America/Montreal" )
) // Returns a `ZonedDateTime` object.
,
y.plusYears(1) // Move to the following year.
.atDay( 1 ) // Get the first of the following year. Returns a `LocalDate`.
.atStartOfDay(
ZoneId.of( "America/Montreal" )
) // Returns a `ZonedDateTime` object.
) ;
31536000000
31556952000=太阳年
使用的是一个太阳年的近似长度,大约365.2425天24小时。这是地球绕太阳运行所需的时间
数学:
365.2425*24*60*60*1000=31556951999.99996≈ 31556952000毫秒
看
31536000000=日历年
在西方历法(格里高利历/ISO)中,我们使用了365年的24小时日,忽略了地球绕太阳运行需要额外的四分之一天这一事实。我们通过每四年增加一天(大约是四的倍数,除了可以被100整除但不能被400整除的年份),来弥补差异
考虑到一个365天、24小时的普通年份,并且没有夏时制(DST)等异常情况,日历年的长度为31536000000毫秒。并非如您在问题中所建议的那样31556952000
31536000000=(365*24*60*60*1000)
看
366天的闰年将是31622400000
毫秒
long millisInYear = ChronoUnit.MILLIS.between ( start , stop );
31622400000=(366*24*60*60*1000)
java.time
现代java.time类取代了与最早版本的java捆绑在一起的旧日期时间类。那些旧的类已经被证明是混乱和麻烦的
ChronoUnit
闰年和其他异常可能意味着一年中意外的毫秒数。因此,如果精度在您的情况下很重要,那么您应该让java.time进行实际计算
该类可以计算特定单位的运行时间
long millisInYear = ChronoUnit.MILLIS.between( start , stop );
我们需要确定一年中第一天和下一年的确切开始时间。我们通过查看LocalDate
类来实现这一点,该类表示一个只包含日期的值,没有一天中的时间,也没有时区
LocalDate startLd = LocalDate.of ( 2015 , 1 , 1 );
LocalDate stopLd = startLd.plusYears ( 1 );
通过指定时区(ZoneId
),我们可以获得时间线上特定时刻的zoneDateTime
对象
ZoneId z = ZoneId.of ( "America/Montreal" );
ZonedDateTime start = startLd.atStartOfDay ( z );
ZonedDateTime stop = stopLd.atStartOfDay ( z );
最后,以毫秒为单位计算经过的时间
long millisInYear = ChronoUnit.MILLIS.between ( start , stop );
start.toString():2015-01-01T00:00-05:00[美国/蒙特利尔]
stop.toString():2016-01-01T00:00-05:00[美国/蒙特利尔]
百万年:31536000000
关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,& 该项目现已启动,建议迁移到类 要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是 您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要
java.sql.*
类
从哪里获得java.time类
- 然后
- 内置的李>
- 标准JavaAPI的一部分,带有捆绑实现
- Java9添加了一些次要功能和修复
- 及
- 大部分java.time功能都在中向后移植到Java6和Java7
-
- 更高版本的Android捆绑包实现了java.time类
- 对于早期的Android(为什么不试试呢?或者查一下32位有符号整数的最大值是多少?@Dave Newton我已经试过了,代码返回了一个我知道不正确的值。一个int在一年中工作几毫秒,但是我计算了错误的值。可能闰年是不相关的…@TonyHopkinson闰年是不相关的。我只是用这个代码在两年之间创建一个随机日期。我使用此日期进行测试,不关心边界条件。因为此页面是在搜索“1年(毫秒)”时出现的,请注意,1年(毫秒)的数值不正确。非闰年的正确值为31536000000,
long millisInYear = ChronoUnit.MILLIS.between ( start , stop );