1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
# -*- coding: utf-8 -*-
# Copyright 2007-2023 The HyperSpy developers
#
# This file is part of RosettaSciIO.
#
# RosettaSciIO is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# RosettaSciIO is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with RosettaSciIO. If not, see <https://www.gnu.org/licenses/#GPL>.
import datetime
import logging
import numpy as np
from dateutil import parser, tz
_logger = logging.getLogger(__name__)
def serial_date_to_ISO_format(serial):
"""
Convert serial_date to a tuple of string (date, time, time_zone) in ISO
format. By default, the serial date is converted in local time zone.
"""
dt_utc = serial_date_to_datetime(serial)
dt_local = dt_utc.astimezone(tz.tzlocal())
return dt_local.date().isoformat(), dt_local.time().isoformat(), dt_local.tzname()
def ISO_format_to_serial_date(date, time, timezone="UTC"):
"""Convert ISO format to a serial date."""
if timezone is None or timezone == "Coordinated Universal Time":
timezone = "UTC"
dt = parser.parse("%sT%s" % (date, time)).replace(tzinfo=tz.gettz(timezone))
return datetime_to_serial_date(dt)
def datetime_to_serial_date(dt):
"""Convert datetime.datetime object to a serial date."""
if dt.tzname() is None:
dt = dt.replace(tzinfo=tz.tzutc())
origin = datetime.datetime(1899, 12, 30, tzinfo=tz.tzutc())
delta = dt - origin
return float(delta.days) + (float(delta.seconds) / 86400.0)
def serial_date_to_datetime(serial):
"""Convert serial date to a datetime.datetime object."""
# Excel date&time format
origin = datetime.datetime(1899, 12, 30, tzinfo=tz.tzutc())
secs = (serial % 1.0) * 86400
delta = datetime.timedelta(int(serial), secs)
return origin + delta
def get_date_time_from_metadata(metadata, formatting="ISO"):
"""
Get the date and time from a metadata tree.
Parameters
----------
metadata : metadata dict
formatting : string, ('ISO', 'datetime', 'datetime64')
Default: 'ISO'. This parameter set the formatting of the date,
and the time, it can be ISO 8601 string, datetime.datetime
or a numpy.datetime64 object. In the later case, the time zone
is not supported.
Returns
-------
string, datetime.datetime or numpy.datetime64 object
"""
md_gen = metadata["General"]
date, time = md_gen.get("date"), md_gen.get("time")
if date and time:
dt = parser.parse(f"{date}T{time}")
time_zone = md_gen.get("time_zone")
if time_zone:
dt = dt.replace(tzinfo=tz.gettz(time_zone))
if dt.tzinfo is None:
# time_zone metadata must be offset string
dt = parser.parse(f"{date}T{time}{time_zone}")
elif not date and time:
dt = parser.parse(f"{time}").time()
elif date and not time:
dt = parser.parse(f"{date}").date()
else:
return None
if formatting == "ISO":
res = dt.isoformat()
elif formatting == "datetime":
res = dt
# numpy.datetime64 doesn't support time zone
elif formatting == "datetime64":
res = np.datetime64(f"{date}T{time}")
return res
def msfiletime_to_unix(msfiletime):
"""Convert microsoft's filetime to unix datetime used in python
built-in datetime
Parameters
----------
msfiletime: 64-bit integer representing number of 10 microsecond ticks
from 1601
Returns
-------
datetime.datetime object"""
return datetime.datetime(1601, 1, 1) + datetime.timedelta(
microseconds=msfiletime / 10
)
|