| 1 | #ifndef AWS_COMMON_DATE_TIME_H |
| 2 | #define AWS_COMMON_DATE_TIME_H |
| 3 | /* |
| 4 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. |
| 5 | * |
| 6 | * Licensed under the Apache License, Version 2.0 (the "License"). |
| 7 | * You may not use this file except in compliance with the License. |
| 8 | * A copy of the License is located at |
| 9 | * |
| 10 | * http://aws.amazon.com/apache2.0 |
| 11 | * |
| 12 | * or in the "license" file accompanying this file. This file is distributed |
| 13 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
| 14 | * express or implied. See the License for the specific language governing |
| 15 | * permissions and limitations under the License. |
| 16 | */ |
| 17 | #include <aws/common/common.h> |
| 18 | |
| 19 | #include <time.h> |
| 20 | |
| 21 | #define AWS_DATE_TIME_STR_MAX_LEN 100 |
| 22 | #define AWS_DATE_TIME_STR_MAX_BASIC_LEN 20 |
| 23 | |
| 24 | struct aws_byte_buf; |
| 25 | struct aws_byte_cursor; |
| 26 | |
| 27 | enum aws_date_format { |
| 28 | AWS_DATE_FORMAT_RFC822, |
| 29 | AWS_DATE_FORMAT_ISO_8601, |
| 30 | AWS_DATE_FORMAT_ISO_8601_BASIC, |
| 31 | AWS_DATE_FORMAT_AUTO_DETECT, |
| 32 | }; |
| 33 | |
| 34 | enum aws_date_month { |
| 35 | AWS_DATE_MONTH_JANUARY = 0, |
| 36 | AWS_DATE_MONTH_FEBRUARY, |
| 37 | AWS_DATE_MONTH_MARCH, |
| 38 | AWS_DATE_MONTH_APRIL, |
| 39 | AWS_DATE_MONTH_MAY, |
| 40 | AWS_DATE_MONTH_JUNE, |
| 41 | AWS_DATE_MONTH_JULY, |
| 42 | AWS_DATE_MONTH_AUGUST, |
| 43 | AWS_DATE_MONTH_SEPTEMBER, |
| 44 | AWS_DATE_MONTH_OCTOBER, |
| 45 | AWS_DATE_MONTH_NOVEMBER, |
| 46 | AWS_DATE_MONTH_DECEMBER, |
| 47 | }; |
| 48 | |
| 49 | enum aws_date_day_of_week { |
| 50 | AWS_DATE_DAY_OF_WEEK_SUNDAY = 0, |
| 51 | AWS_DATE_DAY_OF_WEEK_MONDAY, |
| 52 | AWS_DATE_DAY_OF_WEEK_TUESDAY, |
| 53 | AWS_DATE_DAY_OF_WEEK_WEDNESDAY, |
| 54 | AWS_DATE_DAY_OF_WEEK_THURSDAY, |
| 55 | AWS_DATE_DAY_OF_WEEK_FRIDAY, |
| 56 | AWS_DATE_DAY_OF_WEEK_SATURDAY, |
| 57 | }; |
| 58 | |
| 59 | struct aws_date_time { |
| 60 | time_t timestamp; |
| 61 | char tz[6]; |
| 62 | struct tm gmt_time; |
| 63 | struct tm local_time; |
| 64 | bool utc_assumed; |
| 65 | }; |
| 66 | |
| 67 | AWS_EXTERN_C_BEGIN |
| 68 | |
| 69 | /** |
| 70 | * Initializes dt to be the current system time. |
| 71 | */ |
| 72 | AWS_COMMON_API void aws_date_time_init_now(struct aws_date_time *dt); |
| 73 | |
| 74 | /** |
| 75 | * Initializes dt to be the time represented in milliseconds since unix epoch. |
| 76 | */ |
| 77 | AWS_COMMON_API void aws_date_time_init_epoch_millis(struct aws_date_time *dt, uint64_t ms_since_epoch); |
| 78 | |
| 79 | /** |
| 80 | * Initializes dt to be the time represented in seconds.millis since unix epoch. |
| 81 | */ |
| 82 | AWS_COMMON_API void aws_date_time_init_epoch_secs(struct aws_date_time *dt, double sec_ms); |
| 83 | |
| 84 | /** |
| 85 | * Initializes dt to be the time represented by date_str in format 'fmt'. Returns AWS_OP_SUCCESS if the |
| 86 | * string was successfully parsed, returns AWS_OP_ERR if parsing failed. |
| 87 | * |
| 88 | * Notes for AWS_DATE_FORMAT_RFC822: |
| 89 | * If no time zone information is provided, it is assumed to be local time (please don't do this). |
| 90 | * |
| 91 | * If the time zone is something other than something indicating Universal Time (e.g. Z, UT, UTC, or GMT) or an offset |
| 92 | * from UTC (e.g. +0100, -0700), parsing will fail. |
| 93 | * |
| 94 | * Really, it's just better if you always use Universal Time. |
| 95 | */ |
| 96 | AWS_COMMON_API int aws_date_time_init_from_str( |
| 97 | struct aws_date_time *dt, |
| 98 | const struct aws_byte_buf *date_str, |
| 99 | enum aws_date_format fmt); |
| 100 | |
| 101 | /** |
| 102 | * aws_date_time_init variant that takes a byte_cursor rather than a byte_buf |
| 103 | */ |
| 104 | AWS_COMMON_API int aws_date_time_init_from_str_cursor( |
| 105 | struct aws_date_time *dt, |
| 106 | const struct aws_byte_cursor *date_str_cursor, |
| 107 | enum aws_date_format fmt); |
| 108 | |
| 109 | /** |
| 110 | * Copies the current time as a formatted date string in local time into output_buf. If buffer is too small, it will |
| 111 | * return AWS_OP_ERR. A good size suggestion is AWS_DATE_TIME_STR_MAX_LEN bytes. AWS_DATE_FORMAT_AUTO_DETECT is not |
| 112 | * allowed. |
| 113 | */ |
| 114 | AWS_COMMON_API int aws_date_time_to_local_time_str( |
| 115 | const struct aws_date_time *dt, |
| 116 | enum aws_date_format fmt, |
| 117 | struct aws_byte_buf *output_buf); |
| 118 | |
| 119 | /** |
| 120 | * Copies the current time as a formatted date string in utc time into output_buf. If buffer is too small, it will |
| 121 | * return AWS_OP_ERR. A good size suggestion is AWS_DATE_TIME_STR_MAX_LEN bytes. AWS_DATE_FORMAT_AUTO_DETECT is not |
| 122 | * allowed. |
| 123 | */ |
| 124 | AWS_COMMON_API int aws_date_time_to_utc_time_str( |
| 125 | const struct aws_date_time *dt, |
| 126 | enum aws_date_format fmt, |
| 127 | struct aws_byte_buf *output_buf); |
| 128 | |
| 129 | /** |
| 130 | * Copies the current time as a formatted short date string in local time into output_buf. If buffer is too small, it |
| 131 | * will return AWS_OP_ERR. A good size suggestion is AWS_DATE_TIME_STR_MAX_LEN bytes. AWS_DATE_FORMAT_AUTO_DETECT is not |
| 132 | * allowed. |
| 133 | */ |
| 134 | AWS_COMMON_API int aws_date_time_to_local_time_short_str( |
| 135 | const struct aws_date_time *dt, |
| 136 | enum aws_date_format fmt, |
| 137 | struct aws_byte_buf *output_buf); |
| 138 | |
| 139 | /** |
| 140 | * Copies the current time as a formatted short date string in utc time into output_buf. If buffer is too small, it will |
| 141 | * return AWS_OP_ERR. A good size suggestion is AWS_DATE_TIME_STR_MAX_LEN bytes. AWS_DATE_FORMAT_AUTO_DETECT is not |
| 142 | * allowed. |
| 143 | */ |
| 144 | AWS_COMMON_API int aws_date_time_to_utc_time_short_str( |
| 145 | const struct aws_date_time *dt, |
| 146 | enum aws_date_format fmt, |
| 147 | struct aws_byte_buf *output_buf); |
| 148 | |
| 149 | AWS_COMMON_API double aws_date_time_as_epoch_secs(const struct aws_date_time *dt); |
| 150 | AWS_COMMON_API uint64_t aws_date_time_as_nanos(const struct aws_date_time *dt); |
| 151 | AWS_COMMON_API uint64_t aws_date_time_as_millis(const struct aws_date_time *dt); |
| 152 | AWS_COMMON_API uint16_t aws_date_time_year(const struct aws_date_time *dt, bool local_time); |
| 153 | AWS_COMMON_API enum aws_date_month aws_date_time_month(const struct aws_date_time *dt, bool local_time); |
| 154 | AWS_COMMON_API uint8_t aws_date_time_month_day(const struct aws_date_time *dt, bool local_time); |
| 155 | AWS_COMMON_API enum aws_date_day_of_week aws_date_time_day_of_week(const struct aws_date_time *dt, bool local_time); |
| 156 | AWS_COMMON_API uint8_t aws_date_time_hour(const struct aws_date_time *dt, bool local_time); |
| 157 | AWS_COMMON_API uint8_t aws_date_time_minute(const struct aws_date_time *dt, bool local_time); |
| 158 | AWS_COMMON_API uint8_t aws_date_time_second(const struct aws_date_time *dt, bool local_time); |
| 159 | AWS_COMMON_API bool aws_date_time_dst(const struct aws_date_time *dt, bool local_time); |
| 160 | |
| 161 | /** |
| 162 | * returns the difference of a and b (a - b) in seconds. |
| 163 | */ |
| 164 | AWS_COMMON_API time_t aws_date_time_diff(const struct aws_date_time *a, const struct aws_date_time *b); |
| 165 | |
| 166 | AWS_EXTERN_C_END |
| 167 | |
| 168 | #endif /* AWS_COMMON_DATE_TIME_H */ |
| 169 | |