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 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
Я знаю, что этот 1 год = 31556952000 миллисекунд, поэтому мое умножение как-то отключено.
Может ли кто-нибудь указать, что я делаю неправильно? Должен ли я использовать длинный?
Ответы
Ответ 1
Должен ли я использовать длинный?
Да. Проблема в том, что поскольку MILLIS_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;
Ответ 2
Если на андроиде я предлагаю:
android.text.format.DateUtils
DateUtils.SECOND_IN_MILLIS
DateUtils.MINUTE_IN_MILLIS
DateUtils.HOUR_IN_MILLIS
DateUtils.DAY_IN_MILLIS
DateUtils.WEEK_IN_MILLIS
DateUtils.YEAR_IN_MILLIS
Ответ 3
В то время как другие уже указали арифметическое переполнение, вы также можете попробовать TimeUnit, чтобы решить проблему:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, year);
int daysInYear = calendar.getActualMaximum(Calendar.DAY_OF_YEAR);
System.out.println(TimeUnit.DAYS.toMillis(daysInYear));
Ответ 4
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 * ...
Ответ 5
Вам нужно долго. Инты обернут около 2 миллиардов.
Ответ 6
Вы переполняете тип int
. В Java результат примитивной арифметической операции над двумя int
равен 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;
Ответ 7
Чтобы исправить это, вы можете поместить письмо L после первого: например. 1000L
long MILLS_IN_YEAR = 1000L * 60 * 60 * 24 * 365; // Returns 31536000000
Ответ 8
попробуйте это
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
Ответ 9
31,536,000,000
Учитывая простой год 365 дней с 24-часовыми днями и отсутствие аномалий для учета таких, как летнее время (DST), год 31,536,000,000
миллисекунд. Не 31,556,952,000
, как вы предлагаете в своем Вопросе.
31 536 000 000 = (365 * 24 * 60 * 60 * 1000)
Период високосного хода с 366 днями будет 31,622,400,000
миллисекунды.
31,622,400,000 = (366 * 24 * 60 * 60 * 1000)
java.time
Современные классы java.time заменяют старые классы времени, связанные с самыми ранними версиями Java. Эти старые классы оказались запутанными и неприятными.
ChronoUnit
Високосный год и другие аномалии могут означать неожиданное количество миллисекунд в год. Поэтому вы должны позволить java.time делать фактический расчет, если точность важна в вашей ситуации.
Класс ChronoUnit
может вычислять прошедшее время в определенной единице.
long millisInYear = ChronoUnit.MILLIS.between( start , stop );
Нам нужно определить точный момент начала первого дня дня и следующего года. Мы делаем это, пройдя класс LocalDate
, который представляет значение только для даты без времени и без часового пояса.
LocalDate startLd = LocalDate.of ( 2015 , 1 , 1 );
LocalDate stopLd = startLd.plusYears ( 1 );
Назначая часовой пояс (ZoneId
), мы получаем ZonedDateTime
объекты для определенных моментов на временной шкале.
ZoneId z = ZoneId.of ( "America/Montreal" );
ZonedDateTime start = startLd.atStartOfDay ( z );
ZonedDateTime stop = stopLd.atStartOfDay ( z );
Наконец, вычислите прошедшее время в миллисекундах.
long millisInYear = ChronoUnit.MILLIS.between ( start , stop );
начало: 2015-01-01T00: 00-05: 00 [Америка/Монреаль] | остановка: 2016-01-01T00: 00-05: 00 [Америка/Монреаль] | millisInYear: 31536000000