# encoding: utf-8 # # Copyright 2024 Greg Neagle. # # Licensed under the Apache License, Version 2.0 (the 'License'); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an 'AS IS' BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ dateutils.py Created by Greg Neagle on 2024-04-12. Shared date/time functions """ from __future__ import absolute_import, print_function # PyLint cannot properly find names inside Cocoa libraries, so issues bogus # No name 'Foo' in module 'Bar' warnings. Disable them. # pylint: disable=E0401, E0611 from Foundation import NSDate, NSDateFormatter, NSISO8601DateFormatter from Foundation import NSTimeZone, NSLocale # pylint: enable=E0401, E0611 # Disable PyLint complaining about 'invalid' camelCase names # pylint: disable=C0103 def munkiDateFormatter(fmt=None): """Works with date strings formatted like "1984-01-24 12:34:00 +0000" Which historically was the result of str(). Optionally can use a custom format string. See: http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_Patterns for supported format string options.""" dateFormatter = NSDateFormatter.alloc().init() dateFormatter.setLocale_( NSLocale.localeWithLocaleIdentifier_("en_US_POSIX")) if fmt is None: # default format string fmt = "yyyy-MM-dd HH:mm:ss Z" dateFormatter.setDateFormat_(fmt) dateFormatter.setTimeZone_(NSTimeZone.timeZoneForSecondsFromGMT_(0)) return dateFormatter def stringFromDate(nsdate, fmt=None): """Return a string representing an NSDate. Format of the string defaults to '1984-01-24 12:34:00 +0000'-style strings if format is None. Specify a format of 'ISO8601' for '1984-01-24T12:34:00Z'-style strings or a custom format string.""" if fmt == "ISO8601": dateFormatter = NSISO8601DateFormatter.alloc().init() else: dateFormatter = munkiDateFormatter(fmt=fmt) return dateFormatter.stringFromDate_(nsdate) def dateFromString(dateString): """Attempts to parse a string and return an NSDate. Tries three formats: 1) "1984-01-24 12:34:00 +0000" 2) "1984-01-24T12:34:00Z" 3) "1984-01-24 12:34:00""" # Try classic str() format date = munkiDateFormatter().dateFromString_(dateString) if not date: # try ISO8601 format date = NSISO8601DateFormatter.alloc().init().dateFromString_(dateString) if not date: # one last fallback format to try date = munkiDateFormatter( fmt="yyyy-MM-dd HH:mm:ss").dateFromString_(dateString) return date def format_timestamp(timestamp=None, fmt=None): """Return timestamp as formatted string, in the UTC/GMT timezone. If timestamp isn't given the current time is used.""" if timestamp is None: return stringFromDate(NSDate.new(), fmt=fmt) return stringFromDate( NSDate.dateWithTimeIntervalSince1970_(timestamp), fmt=fmt) if __name__ == '__main__': print('This is a library of support tools for the Munki Suite.')