error Gregorian Calendar java.util.GregorianCalendar [time = 1525903200000, areFieldsSet = true, areAllFieldsSet = true [duplicate]

Просто для удовольствия я играл с представлением поплавков, следуя определениям из стандарта C99, и я написал код ниже.

Код печатает двоичное представление поплавков в 3 отдельных группах

SIGN EXPONENT FRACTION

, и после этого он печатает сумму, которая при суммировании с достаточной точностью покажет значение, которое действительно существует в аппаратном обеспечении.

Поэтому, когда вы пишете float x = 999... компилятор преобразует это число в битовое представление, напечатанное функцией xx, так что сумма, напечатанная функцией yy, будет равна заданному числу.

В действительности эта сумма является только приближение. Для числа 999,999,999 компилятор будет вставлять в бит представление float число 1,000,000,000

После кода я присоединяю консольный сеанс, в котором я вычисляю сумму терминов для обеих констант (минус PI и 999999999) который действительно существует в аппаратном обеспечении, вставленном там компилятором.

#include <stdio.h>
#include <limits.h>

void
xx(float *x)
{
    unsigned char i = sizeof(*x)*CHAR_BIT-1;
    do {
        switch (i) {
        case 31:
             printf("sign:");
             break;
        case 30:
             printf("exponent:");
             break;
        case 23:
             printf("fraction:");
             break;

        }
        char b=(*(unsigned long long*)x&((unsigned long long)1<<i))!=0;
        printf("%d ", b);
    } while (i--);
    printf("\n");
}

void
yy(float a)
{
    int sign=!(*(unsigned long long*)&a&((unsigned long long)1<<31));
    int fraction = ((1<<23)-1)&(*(int*)&a);
    int exponent = (255&((*(int*)&a)>>23))-127;

    printf(sign?"positive" " ( 1+":"negative" " ( 1+");
    unsigned int i = 1<<22;
    unsigned int j = 1;
    do {
        char b=(fraction&i)!=0;
        b&&(printf("1/(%d) %c", 1<<j, (fraction&(i-1))?'+':')' ), 0);
    } while (j++, i>>=1);

    printf("*2^%d", exponent);
    printf("\n");
}

void
main()
{
    float x=-3.14;
    float y=999999999;
    printf("%lu\n", sizeof(x));
    xx(&x);
    xx(&y);
    yy(x);
    yy(y);
}

Вот сеанс консоли, в котором я вычисляю реальное значение float, которое существует в аппаратном обеспечении. Я использовал bc для печати суммы терминов, выводимых основной программой. Можно вставить эту сумму в python repl или что-то подобное.

-- .../terra1/stub
@ qemacs f.c
-- .../terra1/stub
@ gcc f.c
-- .../terra1/stub
@ ./a.out
sign:1 exponent:1 0 0 0 0 0 0 fraction:0 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 1 0 0 0 0 1 1
sign:0 exponent:1 0 0 1 1 1 0 fraction:0 1 1 0 1 1 1 0 0 1 1 0 1 0 1 1 0 0 1 0 1 0 0 0
negative ( 1+1/(2) +1/(16) +1/(256) +1/(512) +1/(1024) +1/(2048) +1/(8192) +1/(32768) +1/(65536) +1/(131072) +1/(4194304) +1/(8388608) )*2^1
positive ( 1+1/(2) +1/(4) +1/(16) +1/(32) +1/(64) +1/(512) +1/(1024) +1/(4096) +1/(16384) +1/(32768) +1/(262144) +1/(1048576) )*2^29
-- .../terra1/stub
@ bc
scale=15
( 1+1/(2) +1/(4) +1/(16) +1/(32) +1/(64) +1/(512) +1/(1024) +1/(4096) +1/(16384) +1/(32768) +1/(262144) +1/(1048576) )*2^29
999999999.999999446351872

Вот и все. Фактически значение 999999999

999999999.999999446351872

Вы также можете проверить с помощью bc, что -3.14 также возмущено. Не забудьте установить коэффициент scale в bc.

Отображаемая сумма - это то, что внутри аппаратного обеспечения. Значение, которое вы получаете, вычисляя его, зависит от установленного вами масштаба. Я установил коэффициент scale равным 15. Математически, с бесконечной точностью, кажется, что это 1 000 000 000.

19
задан Chris Stillwell 10 February 2016 в 22:09
поделиться

4 ответа

Метод

SimpleDateFormat#format принимает параметр Date в качестве параметра. Вы можете получить Date из Calendar, вызвав его метод getTime:

public static String format(GregorianCalendar calendar){
    SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy");
    fmt.setCalendar(calendar);
    String dateFormatted = fmt.format(calendar.getTime());
    return dateFormatted;
}

Также обратите внимание, что месяцы начинаются с 0, поэтому вы, вероятно, имели в виду:

int month = Integer.parseInt(splitDate[1]) - 1;
45
ответ дан assylias 24 August 2018 в 02:52
поделиться

tl; dr

LocalDate.parse(
    "23-Mar-2017" ,
    DateTimeFormatter.ofPattern( "dd-MMM-uuuu" , Locale.US ) 
)

Избегать устаревших классов времени и времени

Вопрос и другие ответы устарели, используя неприятные старые классы времени, которые теперь являются устаревшими, вытесненными классами java.time.

Использование java.time

Кажется, что вы имеете дело только с значениями даты. Поэтому не используйте класс даты и времени. Вместо этого используйте LocalDate. Класс LocalDate представляет значение даты только без времени и без часовой пояс.

Укажите Locale , чтобы определить (а) человеческий язык для перевода имени дня, названия месяца и т. д. и (б) культурных норм, решающих вопросы сокращения, капитализации, пунктуации, разделителей и т. д.

string.

String input = "23-Mar-2017" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MMM-uuuu" , Locale.US ) ;
LocalDate ld = LocalDate.parse( input , f );

Сгенерировать строку.

String output = ld.format( f );

Если вам дали цифры, а не текст для года, месяца и дня месяца, используйте LocalDate.of.

LocalDate ld = LocalDate.of( 2017 , 3 , 23 );  // ( year , month 1-12 , day-of-month )

См. этот код запуска кода в режиме реального времени на IdeOne.com .

input: 23-Mar-2017

ld.toString (): 2017-03-23 ​​

output: 23-Mar-2017


О java.time

Рамка java.time встроена в Java 8 и более поздних версий. Эти классы вытесняют неприятные старые классы времени legacy , такие как java.util.Date , Calendar и & amp; SimpleDateFormat .

Проект Joda-Time , теперь в режиме обслуживания , советует перейти на java.time .

Чтобы узнать больше, см. учебник Oracle . И поиск Stack Overflow для многих примеров и объяснений. Спецификация JSR 310 .

Используя драйвер JDBC , совместимый с JDBC 4.2 или более поздней версией, вы можете обменять java.time напрямую с вашей базой данных. Нет необходимости в строках или java.sql. * Classes.

Где получить классы java.time?

  • Java SE 8 , Java SE 9 и более поздние версии. Часть стандартного Java API с интегрированной реализацией. Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7 Большая часть функций java.time портирована на Java 6 & amp; 7 в ThreeTen-Backport .
  • Android Более поздние версии реализаций пакетов Android для классов java.time. Для более раннего Android проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше). См. Как использовать ThreeTenABP ... .

Проект ThreeTen-Extra расширяет java.time с дополнительными классами. Этот проект является доказательством возможных будущих дополнений к java.time. Здесь вы можете найти некоторые полезные классы, такие как Interval , YearWeek , YearQuarter и more .

1
ответ дан Basil Bourque 24 August 2018 в 02:52
поделиться
  1. Вы помещаете туда два цифры в год. Первый век. И грегорианский календарь начался в 16 веке. Я думаю, вы должны добавить 2000 к году.
  2. Месяц в функции new GregorianCalendar (год, месяц, дни) основан на 0. Вычитайте 1 из месяца.
  3. Измените тело второй функции так:
        String dateFormatted = null;
        SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy");
        try {
            dateFormatted = fmt.format(date);
        }
        catch ( IllegalArgumentException e){
            System.out.println(e.getMessage());
        }
        return dateFormatted;
    

После отладки вы увидите, что просто GregorianCalendar не может быть аргумент fmt.format ();

На самом деле, никто не нуждается в GregorianCalendar в качестве вывода, даже вам говорят возвращать «строку».

Измените заголовок вашей функции формата на

public static String format(Date date) 

и внести соответствующие изменения. fmt.format() с радостью возьмет объект Date.

  1. Всегда, когда возникает неожиданное исключение, поймайте его самостоятельно, не позволяйте машине java делать это. Таким образом, вы поймете проблему.
1
ответ дан Gangnus 24 August 2018 в 02:52
поделиться

SimpleDateFormat, как указывает его имя, форматирует даты. Не календарь. Поэтому, если вы хотите отформатировать GregorianCalendar с помощью SimpleDateFormat, сначала необходимо преобразовать календарь в дату:

dateFormat.format(calendar.getTime());

И то, что вы видите напечатано, - это представление календаря toString (). Предполагаемое использование - отладка. Он не предназначен для отображения даты в графическом интерфейсе. Для этого используйте (Simple) DateFormat.

Наконец, чтобы преобразовать из String в Date, вы также должны использовать (Simple) DateFormat (его метод parse()), а не разделять строку как вы это делаете. Это даст вам объект Date, и вы можете создать календарь из Даты, установив его (Calendar.getInstance()) и установив свое время (calendar.setTime()).

Мое мнение было бы: Google не работает решение здесь. Чтение документации API - это то, что вам нужно сделать.

4
ответ дан JB Nizet 24 August 2018 в 02:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: