Как преобразовать GregorianCalendar в дату и время Python/Jython?

Я программирую на Jython и хотел бы преобразовать экземпляр даты и времени java.util.GregorianCalendar в значение даты и времени Jython.

Я пробовал это:

from java.util import Calendar, GregorianCalendar
import datetime

x = GregorianCalendar.getInstance()

y = datetime(x.YEAR, x.MONTH, x.DAY_OF_MONTH, x.HOUR_OF_DAY, x.MINUTE, x.SECOND, x.MILLISECOND)

Но я получаю следующую ошибку:

TypeError: 'module' object is not callable

Затем я запустил это и был удивлен, увидев неправильные значения, записанные в журнал. Например, год должен быть 2020, но в журнале написано «1».

from java.util import Calendar, GregorianCalendar
import datetime


x = GregorianCalendar.getInstance()

print x
print "Year", x.YEAR
print "Month",x.MONTH
print "Day", x.DAY_OF_MONTH
print "Hour", x.HOUR_OF_DAY
print "Minute", x.MINUTE
print "Second", x.SECOND
print "Millisecond", x.MILLISECOND
print x.getTime()

Журнал:

java.util.GregorianCalendar[time=1591195394508,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Europe/Berlin",offset=3600000,dstSavings=3600000,useDaylight=true,transitions=143,lastRule=java.util.SimpleTimeZone[id=Europe/Berlin,offset=3600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2020,MONTH=5,WEEK_OF_YEAR=23,WEEK_OF_MONTH=1,DAY_OF_MONTH=3,DAY_OF_YEAR=155,DAY_OF_WEEK=4,DAY_OF_WEEK_IN_MONTH=1,AM_PM=1,HOUR=4,HOUR_OF_DAY=16,MINUTE=43,SECOND=14,MILLISECOND=508,ZONE_OFFSET=3600000,DST_OFFSET=3600000]
Year 1
Month 2
Day 5
Hour 11
Minute 12
Second 13
Millisecond 14
Wed Jun 03 16:43:14 CEST 2020

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


person mpdegn    schedule 03.06.2020    source источник
comment
Отвечает ли это на ваш вопрос? Не удается добавить дни в календарь   -  person Ole V.V.    schedule 03.06.2020


Ответы (2)


java.time.ZonedDateTime заменил GregorianCalendar

К вашему сведению, вы используете ужасные классы даты и времени (GregorianCalendar), которые теперь являются устаревшими, вытесненными несколько лет назад современными классами java.time, определенными в JSR 310.

Преобразование с использованием новых методов, добавленных к старым классам. ZonedDateTime заменяет GregorianCalendar.

ZonedDateTime zdt = myGregCal.toZonedDateTime() ;

Приступайте к извлечению частей.

Нет необходимости добавлять единицу к месяцу, так как java.time использует нормальную нумерацию месяцев, 1-12 для января-декабря. Одна из многих причин использовать только java.time, а не GregorianCalendar.

В синтаксисе Java (я не знаю Jython):

int year = zdt.getYear() ; 
int month = zdt.getMonthValue() ;
int day = zdt.getDayOfMonth() ;
int hour = zdt.getHour() ;
int minute = zdt.getMinute() ;
int second = zdt.getSecond() ;
long micro = TimeUnit.NANOSECONDS.toMicros( zdt.getNano() ) ;  // Convert from the nanosecond resolution of java.time to the microsecond resolution of Jython datetime.
String timeZoneId = zdt.getZone().getId() ;

Две проблемы в коде, замеченном в Вопросе:

  • Вы используете миллисекунды, но конструктор для datetime занимает микросекунды. Здесь мы конвертируем наносекунды, используемые в java.time, в микросекунды, используемые в Jython datetime.
  • Вы забыли передать часовой пояс конструктору datetime. Здесь мы извлекаем идентификатор часового пояса, строку в формате Continent/Region, например Europe/Paris или Pacific/Auckland.

К вашему сведению, устаревшие классы Date и GregorianCalendar имеют разрешение в миллисекундах. Тип Jython datetime разрешается в микросекунды. Типы java.time используют разрешение в наносекундах.


Таблица всех типов даты и времени в Java, как современных, так и устаревших


О java.time

< Платформа em>java.time встроена в Java 8 и более поздние версии. Эти классы заменяют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar и SimpleDateFormat.

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

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

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

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

person Basil Bourque    schedule 03.06.2020

Это сделает это:

from java.util import Calendar, GregorianCalendar
import datetime


x = GregorianCalendar.getInstance()

print x
print "Year", x.get(Calendar.YEAR)
print "Month",x.get(Calendar.MONTH)
print "Day", x.get(Calendar.DAY_OF_MONTH)
print "Hour", x.get(Calendar.HOUR_OF_DAY)
print "Minute", x.get(Calendar.MINUTE)
print "Second", x.get(Calendar.SECOND)
print "Millisecond", x.get(Calendar.MILLISECOND)

y = datetime.datetime(x.get(Calendar.YEAR), x.get(Calendar.MONTH)+1,x.get(Calendar.DAY_OF_MONTH), x.get(Calendar.HOUR_OF_DAY), x.get(Calendar.MINUTE), x.get(Calendar.SECOND), x.get(Calendar.MILLISECOND)*1000)

print y
print x.getTime()
person mpdegn    schedule 03.06.2020
comment
Неправильно. Вы не передали часовой пояс из GregorianCalendar в конструктор Jython datetime. - person Basil Bourque; 03.06.2020
comment
@BasilBourque Ты прав. Я отредактировал свой ответ. Миллисекунды теперь умножаются на 1000. Мне все еще нужно выяснить, как передать информацию о часовом поясе из GregorianCalendar в Jython datetime. Я посмотрю на это завтра, может быть. На данный момент я доволен результатом. - person mpdegn; 03.06.2020
comment
Вы не должны быть довольны этим. GregorianCalendar ужасно. Sun, Oracle и сообщество JCP несколько лет назад отказались от этого класса, приняв JSR. 310, и вы тоже. Рассмотрите возможность использования java.time, как показано в моем ответе. - person Basil Bourque; 03.06.2020
comment
Я это понимаю, но не могу использовать java.time, потому что разрабатываю интерфейс между двумя системами. Система A отправляет информацию о дате как GregorianCalendar, а система B ожидает эту информацию о дате как дату и время python. У меня нет доступа ни к одной из систем. - person mpdegn; 08.07.2020
comment
Легко преобразовать в/из GregorianCalendar и ZonedDateTime: GregorianCalendar.from( ZonedDateTime ) и GregorianCalendar::toZonedDateTime. - person Basil Bourque; 08.07.2020