# Copyright (c) 2015 Mirantis, Inc. # # 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 # # http://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. """ The module describes which operations can be done with datetime objects. """ import datetime import time as python_time from yaql.language import specs from yaql.language import yaqltypes from dateutil import parser from dateutil import tz DATETIME_TYPE = datetime.datetime TIMESPAN_TYPE = datetime.timedelta ZERO_TIMESPAN = datetime.timedelta() UTCTZ = yaqltypes.DateTime.utctz def _get_tz(offset): if offset is None: return None if offset == ZERO_TIMESPAN: return UTCTZ return tz.tzoffset(None, seconds(offset)) @specs.name('datetime') @specs.parameter('year', int) @specs.parameter('month', int) @specs.parameter('day', int) @specs.parameter('hour', int) @specs.parameter('minute', int) @specs.parameter('second', int) @specs.parameter('microsecond', int) @specs.parameter('offset', TIMESPAN_TYPE) def build_datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, offset=ZERO_TIMESPAN): """:yaql:datetime Returns datetime object built on year, month, day, hour, minute, second, microsecond, offset. :signature: datetime(year, month, day, hour => 0, minute => 0, second => 0, microsecond => 0, offset => timespan(0)) :arg year: number of years in datetime :argType year: integer between 1 and 9999 inclusive :arg month: number of months in datetime :argType month: integer between 1 and 12 inclusive :arg day: number of days in datetime :argType day: integer between 1 and number of days in given month :arg hour: number of hours in datetime, 0 by default :argType hour: integer between 0 and 23 inclusive :arg minute: number of minutes in datetime, 0 by default :argType minute: integer between 0 and 59 inclusive :arg second: number of seconds in datetime, 0 by default :argType second: integer between 0 and 59 inclusive :arg microsecond: number of microseconds in datetime, 0 by default :argType microsecond: integer between 0 and 1000000-1 :arg offset: datetime offset in microsecond resolution, needed for tzinfo, timespan(0) by default :argType offset: timespan type :returnType: datetime object .. code:: yaql> let(datetime(2015, 9, 29)) -> [$.year, $.month, $.day] [2015, 9, 29] """ zone = _get_tz(offset) return DATETIME_TYPE(year, month, day, hour, minute, second, microsecond, zone) @specs.name('datetime') @specs.parameter('timestamp', yaqltypes.Number()) @specs.parameter('offset', TIMESPAN_TYPE) def datetime_from_timestamp(timestamp, offset=ZERO_TIMESPAN): """:yaql:datetime Returns datetime object built by timestamp. :signature: datetime(timestamp, offset => timespan(0)) :arg timestamp: timespan object to represent datetime :argType timestamp: number :arg offset: datetime offset in microsecond resolution, needed for tzinfo, timespan(0) by default :argType offset: timespan type :returnType: datetime object .. code:: yaql> let(datetime(1256953732)) -> [$.year, $.month, $.day] [2009, 10, 31] """ zone = _get_tz(offset) return DATETIME_TYPE.fromtimestamp(timestamp, tz=zone) @specs.name('datetime') @specs.parameter('string', yaqltypes.String()) @specs.parameter('format__', yaqltypes.String(True)) def datetime_from_string(string, format__=None): """:yaql:datetime Returns datetime object built by string parsed with format. :signature: datetime(string, format => null) :arg string: string representing datetime :argType string: string :arg format: format for parsing input string which should be supported with C99 standard of format codes. null by default, which means parsing with Python dateutil.parser usage :argType format: string :returnType: datetime object .. code:: yaql> let(datetime("29.8?2015")) -> [$.year, $.month, $.day] [2015, 8, 29] yaql> let(datetime("29.8?2015", "%d.%m?%Y"))->[$.year, $.month, $.day] [2015, 8, 29] """ if not format__: result = parser.parse(string) else: result = DATETIME_TYPE.strptime(string, format__) if not result.tzinfo: return result.replace(tzinfo=UTCTZ) return result @specs.name('timespan') @specs.parameter('days', int) @specs.parameter('hours', int) @specs.parameter('minutes', int) @specs.parameter('seconds', yaqltypes.Integer()) @specs.parameter('milliseconds', yaqltypes.Integer()) @specs.parameter('microseconds', yaqltypes.Integer()) def build_timespan(days=0, hours=0, minutes=0, seconds=0, milliseconds=0, microseconds=0): """:yaql:timespan Returns timespan object with specified args. :signature: timespan(days => 0, hours => 0, minutes => 0, seconds => 0, milliseconds => 0, microseconds => 0) :arg days: number of days in timespan, 0 by default :argType days: integer :arg hours: number of hours in timespan, 0 by default :argType hours: integer :arg minutes: number of minutes in timespan, 0 by default :argType minutes: integer :arg seconds: number of seconds in timespan, 0 by default :argType seconds: integer :arg milliseconds: number of microseconds in timespan, 0 by default :argType milliseconds: integer :arg microsecond: number of microseconds in timespan, 0 by default :argType microsecond: integer :returnType: timespan object .. code:: yaql> timespan(days => 1, hours => 2, minutes => 3).hours 26.05 """ return TIMESPAN_TYPE( days=days, hours=hours, minutes=minutes, seconds=seconds, milliseconds=milliseconds, microseconds=microseconds) @specs.yaql_property(TIMESPAN_TYPE) def microseconds(timespan): """:yaql:property microseconds Returns total microseconds in timespan. :signature: timespan.microseconds :returnType: integer .. code:: yaql> timespan(seconds => 1).microseconds 1000000 """ return (86400000000 * timespan.days + 1000000 * timespan.seconds + timespan.microseconds) @specs.yaql_property(TIMESPAN_TYPE) def milliseconds(timespan): """:yaql:property milliseconds Returns total milliseconds in timespan. :signature: timespan.milliseconds :returnType: float .. code:: yaql> timespan(seconds => 1).milliseconds 1000.0 """ return microseconds(timespan) / 1000.0 @specs.yaql_property(TIMESPAN_TYPE) def seconds(timespan): """:yaql:property seconds Returns total seconds in timespan. :signature: timespan.seconds :returnType: float .. code:: yaql> timespan(minutes => 1).seconds 60.0 """ return microseconds(timespan) / 1000000.0 @specs.yaql_property(TIMESPAN_TYPE) def minutes(timespan): """:yaql:property minutes Returns total minutes in timespan. :signature: timespan.minutes :returnType: float .. code:: yaql> timespan(hours => 2).minutes 120.0 """ return microseconds(timespan) / 60000000.0 @specs.yaql_property(TIMESPAN_TYPE) def hours(timespan): """:yaql:property hours Returns total hours in timespan. :signature: timespan.hours :returnType: float .. code:: yaql> timespan(days => 2).hours 48.0 """ return microseconds(timespan) / 3600000000.0 @specs.yaql_property(TIMESPAN_TYPE) def days(timespan): """:yaql:property days Returns total days in timespan. :signature: timespan.days :returnType: float .. code:: yaql> timespan(days => 2, hours => 48).days 4.0 """ return microseconds(timespan) / 86400000000.0 def now(offset=ZERO_TIMESPAN): """:yaql:now Returns the current local date and time. :signature: now(offset => timespan(0)) :arg offset: datetime offset in microsecond resolution, needed for tzinfo, timespan(0) by default :argType offset: timespan type :returnType: datetime .. code:: yaql> let(now()) -> [$.year, $.month, $.day] [2016, 7, 18] yaql> now(offset=>localtz()).hour - now().hour 3 """ zone = _get_tz(offset) return DATETIME_TYPE.now(tz=zone) def localtz(): """:yaql:localtz Returns local time zone in timespan object. :signature: localtz() :returnType: timespan object .. code:: yaql> localtz().hours 3.0 """ if python_time.localtime().tm_isdst: return TIMESPAN_TYPE(seconds=-python_time.altzone) else: return TIMESPAN_TYPE(seconds=-python_time.timezone) def utctz(): """:yaql:utctz Returns UTC time zone in timespan object. :signature: utctz() :returnType: timespan object .. code:: yaql> utctz().hours 0.0 """ return ZERO_TIMESPAN @specs.name('#operator_+') @specs.parameter('dt', yaqltypes.DateTime()) @specs.parameter('ts', TIMESPAN_TYPE) def datetime_plus_timespan(dt, ts): """:yaql:operator + Returns datetime object with added timespan. :signature: left + right :arg left: input datetime object :argType left: datetime object :arg right: input timespan object :argType right: timespan object :returnType: datetime object .. code:: yaql> let(now() + timespan(days => 100)) -> $.month 10 """ return dt + ts @specs.name('#operator_+') @specs.parameter('ts', TIMESPAN_TYPE) @specs.parameter('dt', yaqltypes.DateTime()) def timespan_plus_datetime(ts, dt): """:yaql:operator + Returns datetime object with added timespan. :signature: left + right :arg left: input timespan object :argType left: timespan object :arg right: input datetime object :argType right: datetime object :returnType: datetime object .. code:: yaql> let(timespan(days => 100) + now()) -> $.month 10 """ return ts + dt @specs.name('#operator_-') @specs.parameter('dt', yaqltypes.DateTime()) @specs.parameter('ts', TIMESPAN_TYPE) def datetime_minus_timespan(dt, ts): """:yaql:operator - Returns datetime object with subtracted timespan. :signature: left - right :arg left: input datetime object :argType left: datetime object :arg right: input timespan object :argType right: timespan object :returnType: datetime object .. code:: yaql> let(now() - timespan(days => 100)) -> $.month 4 """ return dt - ts @specs.name('#operator_-') @specs.parameter('dt1', yaqltypes.DateTime()) @specs.parameter('dt2', yaqltypes.DateTime()) def datetime_minus_datetime(dt1, dt2): """:yaql:operator - Returns datetime object dt1 with subtracted dt2. :signature: left - right :arg left: input datetime object :argType left: datetime object :arg right: datetime object to be subtracted :argType right: datetime object :returnType: timespan object .. code:: yaql> let(now() - now()) -> $.microseconds -325 """ return dt1 - dt2 @specs.name('#operator_+') @specs.parameter('ts1', TIMESPAN_TYPE) @specs.parameter('ts2', TIMESPAN_TYPE) def timespan_plus_timespan(ts1, ts2): """:yaql:operator + Returns sum of two timespan objects. :signature: left + right :arg left: input timespan object :argType left: timespan object :arg right: input timespan object :argType right: timespan object :returnType: timespan object .. code:: yaql> let(timespan(days => 1) + timespan(hours => 12)) -> $.hours 36.0 """ return ts1 + ts2 @specs.name('#operator_-') @specs.parameter('ts1', TIMESPAN_TYPE) @specs.parameter('ts2', TIMESPAN_TYPE) def timespan_minus_timespan(ts1, ts2): """:yaql:operator - Returns timespan object with subtracted another timespan object. :signature: left - right :arg left: input timespan object :argType left: timespan object :arg right: input timespan object :argType right: timespan object :returnType: timespan object .. code:: yaql> let(timespan(days => 1) - timespan(hours => 12)) -> $.hours 12.0 """ return ts1 - ts2 @specs.name('#operator_>') @specs.parameter('dt1', yaqltypes.DateTime()) @specs.parameter('dt2', yaqltypes.DateTime()) def datetime_gt_datetime(dt1, dt2): """:yaql:operator > Returns true if left datetime is strictly greater than right datetime, false otherwise. :signature: left > right :arg left: left datetime object :argType left: datetime object :arg right: right datetime object :argType right: datetime object :returnType: boolean .. code:: yaql> datetime(2011, 11, 11) > datetime(2010, 10, 10) true """ return dt1 > dt2 @specs.name('#operator_>=') @specs.parameter('dt1', yaqltypes.DateTime()) @specs.parameter('dt2', yaqltypes.DateTime()) def datetime_gte_datetime(dt1, dt2): """:yaql:operator >= Returns true if left datetime is greater or equal to right datetime, false otherwise. :signature: left >= right :arg left: left datetime object :argType left: datetime object :arg right: right datetime object :argType right: datetime object :returnType: boolean .. code:: yaql> datetime(2011, 11, 11) >= datetime(2011, 11, 11) true """ return dt1 >= dt2 @specs.name('#operator_<') @specs.parameter('dt1', yaqltypes.DateTime()) @specs.parameter('dt2', yaqltypes.DateTime()) def datetime_lt_datetime(dt1, dt2): """:yaql:operator < Returns true if left datetime is strictly less than right datetime, false otherwise. :signature: left < right :arg left: left datetime object :argType left: datetime object :arg right: right datetime object :argType right: datetime object :returnType: boolean .. code:: yaql> datetime(2011, 11, 11) < datetime(2011, 11, 11) false """ return dt1 < dt2 @specs.name('#operator_<=') @specs.parameter('dt1', yaqltypes.DateTime()) @specs.parameter('dt2', yaqltypes.DateTime()) def datetime_lte_datetime(dt1, dt2): """:yaql:operator <= Returns true if left datetime is less or equal to right datetime, false otherwise. :signature: left <= right :arg left: left datetime object :argType left: datetime object :arg right: right datetime object :argType right: datetime object :returnType: boolean .. code:: yaql> datetime(2011, 11, 11) <= datetime(2011, 11, 11) true """ return dt1 <= dt2 @specs.name('#operator_>') @specs.parameter('ts1', TIMESPAN_TYPE) @specs.parameter('ts2', TIMESPAN_TYPE) def timespan_gt_timespan(ts1, ts2): """:yaql:operator > Returns true if left timespan is strictly greater than right timespan, false otherwise. :signature: left > right :arg left: left timespan object :argType left: timespan object :arg right: right timespan object :argType right: timespan object :returnType: boolean .. code:: yaql> timespan(hours => 2) > timespan(hours => 1) true """ return ts1 > ts2 @specs.name('#operator_>=') @specs.parameter('ts1', TIMESPAN_TYPE) @specs.parameter('ts2', TIMESPAN_TYPE) def timespan_gte_timespan(ts1, ts2): """:yaql:operator >= Returns true if left timespan is greater or equal to right timespan, false otherwise. :signature: left >= right :arg left: left timespan object :argType left: timespan object :arg right: right timespan object :argType right: timespan object :returnType: boolean .. code:: yaql> timespan(hours => 24) >= timespan(days => 1) true """ return ts1 >= ts2 @specs.name('#operator_<') @specs.parameter('ts1', TIMESPAN_TYPE) @specs.parameter('ts2', TIMESPAN_TYPE) def timespan_lt_timespan(ts1, ts2): """:yaql:operator < Returns true if left timespan is strictly less than right timespan, false otherwise. :signature: left < right :arg left: left timespan object :argType left: timespan object :arg right: right timespan object :argType right: timespan object :returnType: boolean .. code:: yaql> timespan(hours => 23) < timespan(days => 1) true """ return ts1 < ts2 @specs.name('#operator_<=') @specs.parameter('ts1', TIMESPAN_TYPE) @specs.parameter('ts2', TIMESPAN_TYPE) def timespan_lte_timespan(ts1, ts2): """:yaql:operator <= Returns true if left timespan is less or equal to right timespan, false otherwise. :signature: left <= right :arg left: left timespan object :argType left: timespan object :arg right: right timespan object :argType right: timespan object :returnType: boolean .. code:: yaql> timespan(hours => 23) <= timespan(days => 1) true """ return ts1 <= ts2 @specs.name('#operator_*') @specs.parameter('ts', TIMESPAN_TYPE) @specs.parameter('n', yaqltypes.Number()) def timespan_by_num(ts, n): """:yaql:operator * Returns timespan object built on timespan multiplied by number. :signature: left * right :arg left: timespan object :argType left: timespan object :arg right: number to multiply timespan :argType right: number :returnType: timespan .. code:: yaql> let(timespan(hours => 24) * 2) -> $.hours 48.0 """ return TIMESPAN_TYPE(microseconds=(microseconds(ts) * n)) @specs.name('#operator_*') @specs.parameter('n', yaqltypes.Number()) @specs.parameter('ts', TIMESPAN_TYPE) def num_by_timespan(n, ts): """:yaql:operator * Returns timespan object built on number multiplied by timespan. :signature: left * right :arg left: number to multiply timespan :argType left: number :arg right: timespan object :argType right: timespan object :returnType: timespan .. code:: yaql> let(2 * timespan(hours => 24)) -> $.hours 48.0 """ return TIMESPAN_TYPE(microseconds=(microseconds(ts) * n)) @specs.name('#operator_/') @specs.parameter('ts1', TIMESPAN_TYPE) @specs.parameter('ts2', TIMESPAN_TYPE) def div_timespans(ts1, ts2): """:yaql:operator / Returns result of division of timespan microseconds by another timespan microseconds. :signature: left / right :arg left: left timespan object :argType left: timespan object :arg right: right timespan object :argType right: timespan object :returnType: float .. code:: yaql> timespan(hours => 24) / timespan(hours => 12) 2.0 """ return (0.0 + microseconds(ts1)) / microseconds(ts2) @specs.name('#operator_/') @specs.parameter('ts', TIMESPAN_TYPE) @specs.parameter('n', yaqltypes.Number()) def div_timespan_by_num(ts, n): """:yaql:operator / Returns timespan object divided by number. :signature: left / right :arg left: left timespan object :argType left: timespan object :arg right: number to divide by :argType right: number :returnType: timespan object .. code:: yaql> let(timespan(hours => 24) / 2) -> $.hours 12.0 """ return TIMESPAN_TYPE(microseconds=(microseconds(ts) / n)) @specs.name('#unary_operator_-') @specs.parameter('ts', TIMESPAN_TYPE) def negative_timespan(ts): """:yaql:operator unary - Returns negative timespan. :signature: -arg :arg arg: input timespan object :argType arg: timespan object :returnType: timespan object .. code:: yaql> let(-timespan(hours => 24)) -> $.hours -24.0 """ return -ts @specs.name('#unary_operator_+') @specs.parameter('ts', TIMESPAN_TYPE) def positive_timespan(ts): """:yaql:operator unary + Returns timespan. :signature: +arg :arg arg: input timespan object :argType arg: timespan object :returnType: timespan object .. code:: yaql> let(+timespan(hours => -24)) -> $.hours -24.0 """ return ts @specs.yaql_property(DATETIME_TYPE) def year(dt): """:yaql:property year Returns year of given datetime. :signature: datetime.year :returnType: integer .. code:: yaql> datetime(2006, 11, 21, 16, 30).year 2006 """ return dt.year @specs.yaql_property(DATETIME_TYPE) def month(dt): """:yaql:property month Returns month of given datetime. :signature: datetime.month :returnType: integer .. code:: yaql> datetime(2006, 11, 21, 16, 30).month 11 """ return dt.month @specs.yaql_property(DATETIME_TYPE) def day(dt): """:yaql:property day Returns day of given datetime. :signature: datetime.day :returnType: integer .. code:: yaql> datetime(2006, 11, 21, 16, 30).day 21 """ return dt.day @specs.yaql_property(DATETIME_TYPE) def hour(dt): """:yaql:property hour Returns hour of given datetime. :signature: datetime.hour :returnType: integer .. code:: yaql> datetime(2006, 11, 21, 16, 30).hour 16 """ return dt.hour @specs.yaql_property(DATETIME_TYPE) def minute(dt): """:yaql:property minute Returns minutes of given datetime. :signature: datetime.minute :returnType: integer .. code:: yaql> datetime(2006, 11, 21, 16, 30).minute 30 """ return dt.minute @specs.yaql_property(DATETIME_TYPE) def second(dt): """:yaql:property minute Returns seconds of given datetime. :signature: datetime.second :returnType: integer .. code:: yaql> datetime(2006, 11, 21, 16, 30, 2).second 2 """ return dt.second @specs.yaql_property(DATETIME_TYPE) def microsecond(dt): """:yaql:property microsecond Returns microseconds of given datetime. :signature: datetime.microsecond :returnType: integer .. code:: yaql> datetime(2006, 11, 21, 16, 30, 2, 123).microsecond 123 """ return dt.microsecond @specs.yaql_property(yaqltypes.DateTime()) def date(dt): """:yaql:property date Returns datetime object with only year, month, day and tzinfo part of given datetime. :signature: datetime.date :returnType: datetime object .. code:: yaql> let(datetime(2006, 11, 21, 16, 30, 2, 123).date) -> [$.year, $.month, $.day, $.hour] [2006, 11, 21, 0] """ return DATETIME_TYPE( year=dt.year, month=dt.month, day=dt.day, tzinfo=dt.tzinfo) @specs.yaql_property(yaqltypes.DateTime()) def time(dt): """:yaql:property time Returns timespan object built on datetime without year, month, day and tzinfo part of it. :signature: datetime.time :returnType: timespan object .. code:: yaql> let(datetime(2006, 11, 21, 16, 30).time) -> [$.hours, $.minutes] [16.5, 990.0] """ return dt - date(dt) @specs.yaql_property(DATETIME_TYPE) def weekday(dt): """:yaql:property weekday Returns the day of the week as an integer, Monday is 0 and Sunday is 6. :signature: datetime.weekday :returnType: integer .. code:: yaql> datetime(2006, 11, 21, 16, 30).weekday 1 """ return dt.weekday() @specs.yaql_property(yaqltypes.DateTime()) def utc(dt): """:yaql:property utc Returns datetime converted to UTC. :signature: datetime.utc :returnType: datetime object .. code:: yaql> datetime(2006, 11, 21, 16, 30, offset => timespan(hours => 3)).utc.hour 13 """ return dt - dt.utcoffset() @specs.yaql_property(DATETIME_TYPE) def offset(dt): """:yaql:property offset Returns offset of local time from UTC. :signature: datetime.offset :returnType: timespan .. code:: yaql> datetime(2006, 11, 21, 16, 30, offset => timespan(hours => 3)).offset.hours 3.0 """ return dt.utcoffset() or ZERO_TIMESPAN @specs.yaql_property(DATETIME_TYPE) def timestamp(dt): """:yaql:property timestamp Returns total seconds from datetime(1970, 1, 1) to datetime UTC. :signature: datetime.timestamp :returnType: float .. code:: yaql> datetime(2006, 11, 21, 16, 30).timestamp 1164126600.0 """ return (utc(dt) - DATETIME_TYPE(1970, 1, 1, tzinfo=UTCTZ)).total_seconds() @specs.method @specs.parameter('dt', yaqltypes.DateTime()) @specs.parameter('year', int) @specs.parameter('month', int) @specs.parameter('day', int) @specs.parameter('hour', int) @specs.parameter('minute', int) @specs.parameter('second', int) @specs.parameter('microsecond', int) @specs.parameter('offset', TIMESPAN_TYPE) def replace(dt, year=None, month=None, day=None, hour=None, minute=None, second=None, microsecond=None, offset=None): """:yaql:replace Returns datetime object with applied replacements. :signature: dt.replace(year => null, month => null, day => null, hour => null, minute => null, second => null, microsecond => null, offset => null) :receiverArg dt: input datetime object :argType dt: datetime object :arg year: number of years to replace, null by default which means no replacement :argType year: integer between 1 and 9999 inclusive :arg month: number of months to replace, null by default which means no replacement :argType month: integer between 1 and 12 inclusive :arg day: number of days to replace, null by default which means no replacement :argType day: integer between 1 and number of days in given month :arg hour: number of hours to replace, null by default which means no replacement :argType hour: integer between 0 and 23 inclusive :arg minute: number of minutes to replace, null by default which means no replacement :argType minute: integer between 0 and 59 inclusive :arg second: number of seconds to replace, null by default which means no replacement :argType second: integer between 0 and 59 inclusive :arg microsecond: number of microseconds to replace, null by default which means no replacement :argType microsecond: integer between 0 and 1000000-1 :arg offset: datetime offset in microsecond resolution to replace, null by default which means no replacement :argType offset: timespan type :returnType: datetime object .. code:: yaql> datetime(2015, 9, 29).replace(year => 2014).year 2014 """ replacements = {} if year is not None: replacements['year'] = year if month is not None: replacements['month'] = month if day is not None: replacements['day'] = day if hour is not None: replacements['hour'] = hour if minute is not None: replacements['minute'] = minute if second is not None: replacements['second'] = second if microsecond is not None: replacements['microsecond'] = microsecond if offset is not None: replacements['tzinfo'] = _get_tz(offset) return dt.replace(**replacements) @specs.method @specs.parameter('dt', yaqltypes.DateTime()) @specs.parameter('format__', yaqltypes.String()) def format_(dt, format__): """:yaql:format Returns a string representing datetime, controlled by a format string. :signature: dt.format(format) :receiverArg dt: input datetime object :argType dt: datetime object :arg format: format string :argType format: string :returnType: string .. code:: yaql> now().format("%A, %d. %B %Y %I:%M%p") "Tuesday, 19. July 2016 08:49AM" """ return dt.strftime(format__) def is_datetime(value): """:yaql:isDatetime Returns true if value is datetime object, false otherwise. :signature: isDatetime(value) :arg value: input value :argType value: any :returnType: boolean .. code:: yaql> isDatetime(now()) true yaql> isDatetime(datetime(2010, 10, 10)) true """ return isinstance(value, DATETIME_TYPE) def is_timespan(value): """:yaql:isTimespan Returns true if value is timespan object, false otherwise. :signature: isTimespan(value) :arg value: input value :argType value: any :returnType: boolean .. code:: yaql> isTimespan(now()) false yaql> isTimespan(timespan()) true """ return isinstance(value, TIMESPAN_TYPE) def register(context): functions = ( build_datetime, build_timespan, datetime_from_timestamp, datetime_from_string, now, localtz, utctz, utc, days, hours, minutes, seconds, milliseconds, microseconds, datetime_plus_timespan, timespan_plus_datetime, datetime_minus_timespan, datetime_minus_datetime, timespan_plus_timespan, timespan_minus_timespan, datetime_gt_datetime, datetime_gte_datetime, datetime_lt_datetime, datetime_lte_datetime, timespan_gt_timespan, timespan_gte_timespan, timespan_lt_timespan, timespan_lte_timespan, negative_timespan, positive_timespan, timespan_by_num, num_by_timespan, div_timespans, div_timespan_by_num, year, month, day, hour, minute, second, microsecond, weekday, offset, timestamp, date, time, replace, format_, is_datetime, is_timespan ) for func in functions: context.register_function(func)