Подтвердить что ты не робот

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 миллисекунд, поэтому мое умножение как-то отключено.

Может ли кто-нибудь указать, что я делаю неправильно? Должен ли я использовать длинный?

4b9b3361

Ответ 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