/*====================================================================== FILE: icaltime.h CREATOR: eric 02 June 2000 SPDX-FileCopyrightText: 2000, Eric Busboom SPDX-License-Identifier: LGPL-2.1-only OR MPL-2.0 The Original Code is eric. The Initial Developer of the Original Code is Eric Busboom ======================================================================*/ /** * @file icaltime.h * @brief Defines the data structure for representing date-times. * * struct icaltimetype is a pseudo-object that abstracts time handling. * * It can represent either a DATE or a DATE-TIME (floating, UTC or in a * given timezone), and it keeps track internally of its native timezone. * * The typical usage is to call the correct constructor specifying the * desired timezone. If this is not known until a later time, the * correct behavior is to specify a NULL timezone and call * icaltime_convert_to_zone() at a later time. * * There are several ways to create a new icaltimetype: * * - icaltime_null_time() * - icaltime_null_date() * - icaltime_current_time_with_zone() * - icaltime_today() * - icaltime_from_timet_with_zone(icaltime_t tm, int is_date, * icaltimezone *zone) * - icaltime_from_day_of_year(int doy, int year) * * icaltimetype objects can be converted to different formats: * * - icaltime_as_timet(struct icaltimetype tt) * - icaltime_as_timet_with_zone(struct icaltimetype tt, icaltimezone *zone) * - icaltime_as_ical_string(struct icaltimetype tt) * * Accessor methods include: * * - icaltime_get_timezone(struct icaltimetype t) * - icaltime_get_tzid(struct icaltimetype t) * - icaltime_set_timezone(struct icaltimetype t, const icaltimezone *zone) * - icaltime_day_of_year(struct icaltimetype t) * - icaltime_day_of_week(struct icaltimetype t) * - icaltime_start_doy_week(struct icaltimetype t, int fdow) * * Query methods include: * * - icaltime_is_null_time(struct icaltimetype t) * - icaltime_is_valid_time(struct icaltimetype t) * - icaltime_is_date(struct icaltimetype t) * - icaltime_is_utc(struct icaltimetype t) * * Modify, compare and utility methods include: * * - icaltime_compare(struct icaltimetype a,struct icaltimetype b) * - icaltime_compare_date_only(struct icaltimetype a, struct icaltimetype b) * - icaltime_adjust(struct icaltimetype *tt, int days, int hours, * int minutes, int seconds); * - icaltime_normalize(struct icaltimetype t); * - icaltime_convert_to_zone(const struct icaltimetype tt, icaltimezone *zone); */ #ifndef ICALTIME_H #define ICALTIME_H #include "libical_ical_export.h" #include "icaltime_p.h" #include #include /// @cond PRIVATE /* An opaque struct representing a timezone. We declare this here to avoid a circular dependency. */ #if !defined(ICALTIMEZONE_DEFINED) #define ICALTIMEZONE_DEFINED typedef struct _icaltimezone icaltimezone; #endif /// @endcond /** * Structure to represent a date or date-time. */ struct icaltimetype { int year; /**< Actual year, e.g. 2001. */ int month; /**< 1 (Jan) to 12 (Dec). */ int day; /**< 1-31, month dependent */ int hour; /**< 0-23 */ int minute; /**< 0-59 */ int second; /**< 0-59 */ int is_date; /**< 1 -> interpret this as date. */ int is_daylight; /**< 1 -> time is in daylight savings time. */ const icaltimezone *zone; /**< timezone */ }; typedef struct icaltimetype icaltimetype; /// @cond PRIVATE #define ICALTIMETYPE_INITIALIZER {0, 0, 0, 0, 0, 0, 0, 0, 0} /// @endcond /** * Construct an icaltimetype with null time. * * @returns A null time icaltimetype, which indicates no time has been set. *This time represents the beginning of the epoch. */ LIBICAL_ICAL_EXPORT struct icaltimetype icaltime_null_time(void); /** * Construct an icaltimetype with null date. * * @returns A null date icaltimetype, which indicates no time has been set. */ LIBICAL_ICAL_EXPORT struct icaltimetype icaltime_null_date(void); /** * Construct an icaltimeype with the current time in the specified timezone. * * @param zone is the timezone to use * * @returns The current time in the given timezone, as an icaltimetype. */ LIBICAL_ICAL_EXPORT struct icaltimetype icaltime_current_time_with_zone(const icaltimezone *zone); /** @brief Convenience constructor. * * @returns The current day as an icaltimetype, with is_date set. */ LIBICAL_ICAL_EXPORT struct icaltimetype icaltime_today(void); /** @brief Constructor. * * @param tm The time expressed as seconds past UNIX epoch * @param is_date Boolean: 1 means we should treat tm as a DATE * @param zone The timezone tm is in, NULL means to treat tm as a * floating time * * @return a new icaltime instance, initialized to the given time, * optionally using the given timezone. * * If the caller specifies the is_date param as TRUE, the returned * object is of DATE type, otherwise the input is meant to be of * DATE-TIME type. * If the zone is not specified (NULL zone param) the time is taken * to be floating, that is, valid in any timezone. Note that, in * addition to the uses specified in [RFC5545], this can be used * when doing simple math on couples of times. * If the zone is specified (UTC or otherwise), it's stored in the * object and it's used as the native timezone for this object. * This means that the caller can convert this time to a different * target timezone with no need to store the source timezone. * */ LIBICAL_ICAL_EXPORT struct icaltimetype icaltime_from_timet_with_zone(const icaltime_t tm, const bool is_date, const icaltimezone *zone); /** * Creates a time from a ISO-8601-2004 string, per https://tools.ietf.org/html/rfc5545#section-3.3.5. * * @param str is a string containing a valid DATE-TIME per rfc5545 [ISO-8601-2004] * * The string format is based on the [ISO.8601.2004] spec in one of 3 legal forms: * * - DATE WITH LOCAL TIME "19980118T230000" * - DATE WITH UTC TIME "19980119T070000Z" * - DATE WITH LOCAL TIME AND TIME ZONE REFERENCE "TZID=America/New_York:19980119T020000" * * That is to say, the basic format for time is T[hh][mm][ss] per ISO-8601-2004 * * @return the icaltimetype representation of the specified date or date-time string. */ LIBICAL_ICAL_EXPORT struct icaltimetype icaltime_from_string(const char *str); /** * Creates a new time, given a day of year and a year. * * @param doy in integer day of the year. Zero and negative numbers represent days of the previous year. * @param year the year * * @note that Jan 1 is day 1, not 0. * @note no sanity or error checking is done for the inputs; it's up to the * caller to provide reasonable values. * * @return a new time, given the day of year and a year. */ LIBICAL_ICAL_EXPORT struct icaltimetype icaltime_from_day_of_year(const int doy, const int year); /** * Compute the time as seconds past the UNIX epoch. * * This function probably won't do what you expect. In particular, you should * only pass an icaltime in UTC, since no conversion is done. Even in that case, * it's probably better to just use icaltime_as_timet_with_zone(). * * @param tt is the icaltimetype * * The return value is defined for dates ranging from 1902-01-01 (incl.) up to 10000-01-01 (excl.) * if time_t has a size of 64 bit and up to 2038-01-18 (excl.) if it has a size of 32 bit. * * @return the time as seconds past the UNIX epoch. */ LIBICAL_ICAL_EXPORT icaltime_t icaltime_as_timet(const struct icaltimetype tt); /** * Computes the time as seconds past the UNIX epoch, using the given timezone. * * This convenience method combines a call to icaltime_convert_to_zone() * with a call to icaltime_as_timet(). * * If the input timezone is null, no conversion is done; that is, the * time is simply returned as icaltime_t in its native timezone. * * @param tt the time to convert * @param zone The timezone to use. NULL means no conversion. * * @return the time as seconds past the UNIX epoch, using the given timezone. */ LIBICAL_ICAL_EXPORT icaltime_t icaltime_as_timet_with_zone(const struct icaltimetype tt, const icaltimezone *zone); /** * Returns a string representation of the time, in RFC5545 format. * * @param tt an icaltimetype, presumably containing valid data. * * @note The string is owned by the caller and must be freed accordingly. * @note No sanity or error checking is performed on the input time @p tt. * * @return a string representation of the @p tt in RFC5545 format. * * @see icaltime_as_ical_string_r */ LIBICAL_ICAL_EXPORT const char *icaltime_as_ical_string(const struct icaltimetype tt); /** * Returns a string representation of the time, in RFC5545 format. * * @param tt an icaltimetype, presumably containing valid data. * * @note The string is owned by the caller and must be freed accordingly. * @note No sanity or error checking is performed on the input time @p tt. * * @return a string representation of the time, in RFC5545 format. * * @see icaltime_as_ical_string */ LIBICAL_ICAL_EXPORT char *icaltime_as_ical_string_r(const struct icaltimetype tt); /** * Return the timezone for an icaltimetype. * * @param t is the icaltimetype * * @return a pointer to the @p t timezone. */ LIBICAL_ICAL_EXPORT const icaltimezone *icaltime_get_timezone(const struct icaltimetype t); /** * Returns the tzid for an icaltimetype. * * @param t is the icaltimetype * * @return a string containing the tzid, or NULL for a floating time. */ LIBICAL_ICAL_EXPORT const char *icaltime_get_tzid(const struct icaltimetype t); /** * Sets the timezone for an icaltimetype. * * @param t is the icaltimetype * @param zone is the timezone to use * * Forces the icaltime to be interpreted relative to another timezone. * The returned time represents the same time as @p t, but relative to * the new @p zone. * * For example, modifying July 20 1969, 8:17 PM UTC to the EDT time zone * would return a time representing July 20 1969, 8:17 PM EDT. * * If you need to do timezone conversion, applying offset adjustments, * then you should use icaltime_convert_to_zone instead. * * If @p t is of type `DATE`, its timezone is not modified and the returned * time is an exact copy of @p t. * * @return a icaltimetype computed from @p t with the timezone @p zone. */ LIBICAL_ICAL_EXPORT struct icaltimetype icaltime_set_timezone(struct icaltimetype *t, const icaltimezone *zone); /** * Computes the day of the year for the specified icaltimetype, counting * from 1 (Jan 1st). * * @param t is the icaltimetype * * @return the day of the year for @p t (1-366). Returns 0 if the specified * icaltimetype is invalid (eg. month less than 1 or greater than 12). */ LIBICAL_ICAL_EXPORT int icaltime_day_of_year(const struct icaltimetype t); /** * Computes the day of the week for the specified icaltimetype. * * @param t is the icaltimetype * * @return the day of the week (Sunday is 1, and Saturday is 7) for the time @p t. */ LIBICAL_ICAL_EXPORT int icaltime_day_of_week(const struct icaltimetype t); /** * Returns the day of the year for the first day of the week * that the given time is within. * * This uses the first day of the week that contains the given time, * which is a Sunday. It returns the day of the year for the resulting day. * * @param t is the icaltimetype * @param fdow is the first day of the week expressed as an integer (1-7) * * @return the day of the year for the Sunday of the week that the given @p t is within. */ LIBICAL_ICAL_EXPORT int icaltime_start_doy_week(const struct icaltimetype t, int fdow); /** * Determine if the specified icaltimetype contain "null" time, where * "null" time means that all the contents are 0. * * @param t is the icaltimetype * * @return true if @p t represents "null" time; false otherwise. */ LIBICAL_ICAL_EXPORT bool icaltime_is_null_time(const struct icaltimetype t); /** * Determine if the specified icaltimetype is a valid DATE. * * @param t is the icaltimetype * * This is usually the result of creating a new time type but not * clearing it, or setting one of the flags to an illegal value. * * @return true if contents of @p t are valid; false otherwise. */ LIBICAL_ICAL_EXPORT bool icaltime_is_valid_time(const struct icaltimetype t); /** * Determine if the specified icaltimetype is a DATE. * * @param t is the icaltimetype * * @return true if the @p t is a DATE (rather than a DATE-TIME); false otherwise. */ LIBICAL_ICAL_EXPORT bool icaltime_is_date(const struct icaltimetype t); /** * Determine if the specified icaltimetype is relative to the UTC zone. * @todo We should only check the zone. * * @param t is the icaltimetype * * @return true if @p t is relative to UTC zone; false otherwise. */ LIBICAL_ICAL_EXPORT bool icaltime_is_utc(const struct icaltimetype t); /** * Compares to icaltimetypes for equality. * This converts both times to the UTC timezone and compares them. * * @param a is the first icaltimetype to compare * @param b is the second icaltimetype to compare * * @return -1, 0, or 1 to indicate that a is less than b, a equals b, * or a is greater than b, respectively. * * @see icaltime_compare_date_only, icaltime_compare_date_only_tz */ LIBICAL_ICAL_EXPORT int icaltime_compare(const struct icaltimetype a, const struct icaltimetype b); /** * Like icaltime_compare, but only use the date parts. * This converts both times to the UTC timezone and compares their date * components. * * @param a is the first icaltimetype to compare * @param b is the second icaltimetype to compare * * @return -1, 0, or 1 to indicate that a is less than b, a equals b, * or a is greater than b, respectively. * * @see icaltime_compare, icaltime_compare_date_only_tz */ LIBICAL_ICAL_EXPORT int icaltime_compare_date_only(const struct icaltimetype a, const struct icaltimetype b); /** * Like icaltime_compare, but only use the date parts; accepts timezone. * This converts both times to the given timezone and compares their date * components. * * @param a is the first icaltimetype to compare * @param b is the second icaltimetype to compare * @param tz is the timezone to use * * @return -1, 0, or 1 to indicate that a is less than b, a equals b, * or a is greater than b, respectively. * * @see icaltime_compare, icaltime_compare_date_only */ LIBICAL_ICAL_EXPORT int icaltime_compare_date_only_tz(const struct icaltimetype a, const struct icaltimetype b, icaltimezone *tz); /** * Adds or subtracts time from an icaltimetype. * * Adds or subtracts a time from an icaltimetype. This time is given * as a number of days, hours, minutes and seconds. * * @param tt is a pointer to a valid icaltimetype * @param days is the number of days adjustment * @param hours is the number of hours adjustment * @param minutes is the number of minutes adjustment * @param seconds is the number of seconds adjustment * * @note This function is identical to the static icaltimezone_adjust_change() * except for the type of the first parameter. */ LIBICAL_ICAL_EXPORT void icaltime_adjust(struct icaltimetype *tt, const int days, const int hours, const int minutes, const int seconds); /** * Normalizes the icaltime, so all of the time components * are in their normal ranges. * * @param tt is the icaltimetype to normalize * * For instance, given a time with minutes=70, the minutes will be * reduced to 10 and the hour incremented. This allows the caller to * do arithmetic on times without worrying about overflow or underflow. * * @return an icaltimetype containing the normalized @p tt. */ LIBICAL_ICAL_EXPORT struct icaltimetype icaltime_normalize(const struct icaltimetype tt); /** * Converts a time from its native timezone to a given timezone. * * @param tt is the icaltimetype to convert * @param zone is the timezone to use * * If @p tt is a date, the timezone is not converted and the returned * time is an exact copy of @p tt. * * If it's a floating time, the returned object * represents the same time relative to @p zone. * For example, if @p tt represents 9:30 AM floating and @p zone * is the GMT timezone, the returned object will represent 9:30 AM GMT. * * Otherwise, the time will be converted to @p zone, and its timezone * property updated to @p zone. * * For example, July 20 1969, 8:17 PM UTC would be converted to July 20 * 1969, 4:17 PM EDT. * * @return an icaltimetype containing the timezone shifted @p tt. */ LIBICAL_ICAL_EXPORT struct icaltimetype icaltime_convert_to_zone(const struct icaltimetype tt, icaltimezone *zone); /** * Returns the number of days in the given month. * * @param month is a month number (1-12) * @param year is the year (e.g. 2001) * * @return the number of days in the specified month. */ LIBICAL_ICAL_EXPORT int icaltime_days_in_month(const int month, const int year); /** * Returns whether the specified year is a leap year. * * @param year is the year (e.g. 2001) * * @return true if the @p year is a leap year; false otherwise. */ LIBICAL_ICAL_EXPORT bool icaltime_is_leap_year(const int year); /** * Returns the number of days in a specified year. * * @param year is year (e.g. 2001) * * @return the number of days in the specified year; ie, 365 unless * @p year is a leap year. */ LIBICAL_ICAL_EXPORT int icaltime_days_in_year(const int year); #endif /* !ICALTIME_H */ /* kate: syntax C; */