Просто для удовольствия я играл с представлением поплавков, следуя определениям из стандарта 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.
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;
LocalDate.parse(
"23-Mar-2017" ,
DateTimeFormatter.ofPattern( "dd-MMM-uuuu" , Locale.US )
)
Вопрос и другие ответы устарели, используя неприятные старые классы времени, которые теперь являются устаревшими, вытесненными классами 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
blockquote>
О 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 .
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.
SimpleDateFormat, как указывает его имя, форматирует даты. Не календарь. Поэтому, если вы хотите отформатировать GregorianCalendar с помощью SimpleDateFormat, сначала необходимо преобразовать календарь в дату:
dateFormat.format(calendar.getTime());
И то, что вы видите напечатано, - это представление календаря toString (). Предполагаемое использование - отладка. Он не предназначен для отображения даты в графическом интерфейсе. Для этого используйте (Simple) DateFormat.
Наконец, чтобы преобразовать из String в Date, вы также должны использовать (Simple) DateFormat (его метод parse()
), а не разделять строку как вы это делаете. Это даст вам объект Date, и вы можете создать календарь из Даты, установив его (Calendar.getInstance()
) и установив свое время (calendar.setTime()
).
Мое мнение было бы: Google не работает решение здесь. Чтение документации API - это то, что вам нужно сделать.