Extraer el día del año y el día juliano de una fecha de cadena

Tengo una cadena "2012.11.07" en python. Necesito convertirlo en objeto de fecha y luego obtener un valor entero del día del año y también del día juliano . ¿Es posible?

Primero, puede convertirlo en un objeto datetime.datetime como este:

 >>> import datetime >>> fmt = '%Y.%m.%d' >>> s = '2012.11.07' >>> dt = datetime.datetime.strptime(s, fmt) >>> dt datetime.datetime(2012, 11, 7, 0, 0) 

Luego, puede usar los métodos en datetime para obtener lo que desea … excepto que datetime no tiene la función que desea directamente, por lo que necesita convertirla en una tupla de tiempo.

 >>> tt = dt.timetuple() >>> tt.tm_yday 312 

El término “día juliano” tiene algunos significados diferentes. Si está buscando el 2012312 , debe hacerlo indirectamente, por ejemplo, uno de los siguientes.

 >>> int('%d%03d' % (tt.tm_year, tt.tm_yday)) 2012312 >>> tt.tm_year * 1000 + tt.tm_yday 2012312 

Si estás buscando un significado diferente, deberías poder averiguarlo desde aquí. Por ejemplo, si quiere el significado de “días desde el 1 de enero de 4713 a. C.” y tiene una fórmula que requiere el año gregoriano y el día a año, tiene esos dos valores arriba para completar. (Si tiene una fórmula que toma el año, el mes y el día gregorianos, ni siquiera necesita el paso de tiempo.) Si no puede averiguar a dónde ir desde allí, solicite más detalles.

Si no tiene una fórmula, y tal vez incluso si ya la tiene, su mejor opción es buscar en PyPI y ActiveState los módulos preexistentes. Por ejemplo, una búsqueda rápida apareció algo llamado jdcal . Nunca lo había visto antes, pero una instalación rápida de pip install jdcal y un breve pip install jdcal Léame, y pude hacer esto:

 >>> sum(jdcal.gcal2jd(dt.year, dt.month, dt.day)) 2456238.5 

Ese es el mismo resultado que el convertidor de fecha de USN Julian me dio.

Si desea un día juliano integral, en lugar de una fecha juliana fraccionaria, debe decidir qué dirección desea redondear: hacia 0, hacia el infinito negativo, redondeando el mediodía hasta el día siguiente, redondeando el mediodía hacia los días pares, etc. (Tenga en cuenta que La fecha juliana se define como el inicio desde el mediodía del 1 de enero de 4713 aC, por lo que la mitad del 7 de noviembre de 2012 es 2456238, la otra mitad es 2456239, y solo usted sabe cuál de los que desea …) Por ejemplo, para redondear hacia 0:

 >>> int(sum(jdcal.gcal2jd(dt.year, dt.month, dt.day))) 2456238 

Para simplificar los pasos iniciales de la respuesta de abarnert:

 from dateutil import parser s = '2012.11.07' dt = parser.parse(s) 

Luego aplica el rest de la respuesta de abanert.

Esta funcionalidad (conversión de cadenas de fecha a fecha / hora juliana) también está presente en el módulo astropy . Por favor, consulte su documentación para más detalles. La implementación de astropy es especialmente útil para las conversiones fáciles a la hora juliana, en lugar de solo la fecha juliana.

Ejemplo de solución para la pregunta original:

 >>> import astropy.time >>> import dateutil.parser >>> dt = dateutil.parser.parse('2012.11.07') >>> time = astropy.time.Time(dt) >>> time.jd 2456238.5 >>> int(time.jd) 2456238 

Para cálculos rápidos, puede encontrar el día del año y el número del día juliano utilizando solo el módulo datetime stdlib:

 #!/usr/bin/env python3 from datetime import datetime, timedelta DAY = timedelta(1) JULIAN_EPOCH = datetime(2000, 1, 1, 12) # noon (the epoch name is unrelated) J2000_JD = timedelta(2451545) # julian epoch in julian dates dt = datetime.strptime("2012.11.07", "%Y.%m.%d") # get datetime object day_of_year = (dt - datetime(dt.year, 1, 1)) // DAY + 1 # Jan the 1st is day 1 julian_day = (dt.replace(hour=12) - JULIAN_EPOCH + J2000_JD) // DAY print(day_of_year, julian_day) # 312 2456239 

Otra forma de obtener day_of_year :

 import time day_of_year = time.strptime("2012.11.07", "%Y.%m.%d").tm_yday 

julian_day en el código anterior es “el número del día juliano asociado con el día solar – el número asignado a un día en un conteo continuo de días comenzando con el día juliano 0 asignado al día que comienza en el medio día de Greenwich el 1 de enero de 4713 BC, calendario proleptico juliano -4712 ” .

La documentación del módulo de time usa el término “día juliano” de manera diferente:

Jn El día juliano n (1 <= n <= 365). Los días bisiestos no se cuentan, por lo que en todos los años, el 28 de febrero es el día 59 y el 1 de marzo es el día 60.
n El día juliano de base cero (0 <= n <= 365). Los días bisiestos se cuentan y es posible referirse al 29 de febrero.

es decir, el día juliano de base cero es day_of_year - 1 aquí. Y el primero ( Jn ) es day_of_year - (calendar.isleap(dt.year) and day_of_year > 60) – los días que comienzan el 1 de marzo se desplazan para excluir el día bisiesto.

También hay un término relacionado: fecha juliana . El número del día juliano es un número entero. La fecha juliana es inherentemente fraccional: “La fecha juliana (JD) de cualquier instante es el número del día juliano para el mediodía anterior más la fracción del día desde ese instante”.

En general, para evitar el manejo de casos perimetrales, use una biblioteca para calcular el día de Julian como lo sugiere @abarnert .

Para obtener el día juliano, use el método datetime.date.toordinal y agregue un desplazamiento fijo.

El día de Julián es el número de días desde el 1 de enero de 4713 a. C. a las 12:00 en el calendario juliano proléptico, o el 24 de noviembre de 4714 a. C. a las 12:00 en el calendario gregoriano proleptico . Tenga en cuenta que cada día juliano comienza al mediodía, no a la medianoche.

La función toordinal devuelve el número de días desde el 31 de diciembre, 1 AC a las 00:00 en el calendario gregoriano proleptico (en otras palabras, el 1 de enero, 1 AD a las 00:00 es el comienzo del día 1, no el día 0). Tenga en cuenta que el 1 aC precede directamente al 1 AD, no hubo año 0, ya que el número cero no se inventó hasta muchos siglos después.

 import datetime datetime.date(1,1,1).toordinal() # 1 

Simplemente agregue 1721424.5 al resultado de toordinal para obtener el día Juliano.

Otra respuesta ya explicó cómo analizar la cadena con la que comenzó y convertirla en un objeto datetime.date . Para que puedas encontrar el día juliano de la siguiente manera:

 import datetime my_date = datetime.date(2012,11,7) # time = 00:00:00 my_date.toordinal() + 1721424.5 # 2456238.5 

De los ejemplos anteriores, aquí está el trazador de líneas (no juliano):

 import datetime doy = datetime.datetime.strptime('2014-01-01', '%Y-%m-%d').timetuple().tm_yday 
 def JulianDate_to_date(y, jd): month = 1 while jd - calendar.monthrange(y,month)[1] > 0 and month <= 12: jd = jd - calendar.monthrange(y,month)[1] month += 1 date = datetime.date(y,month,jd).strftime("%m/%d/%Y") return date 

Según este artículo, hay una fórmula de una línea inédita creada por Fliegel y Van Flandern para calcular una fecha gregoriana a una fecha juliana:

 JD = 367 * year - 7 * (year + (month + 9)/12)/4 - 3 * ((year + (month - 9)/7)/100 + 1)/4 + 275 * month/9 + day + 1721029 

Esto fue compactado por PM Muller y RN Wimberly del Jet Propulsion Laboratory, Pasadena, California para fechas posteriores a marzo de 1900 para:

 JD = 367 * year - 7 * (year + (month + 9)/12)/4 + 275 * month/9 + day + 1721014 

Estas fórmulas están desactivadas en 0.5, así que solo reste 0.5 de las fórmulas.

Usa alguna manipulación de cadenas para extraer los datos y serás bueno

 >>> year, month, day = map(int,"2018.11.02".split(".")) >>> 367 * year - 7 * (year + (month + 9)/12)/4 + 275 * month/9 + day + 1721014 - 0.5 2458424.5