----------------------------------------------------------------------- -- util-dates-formats -- Date Format ala strftime -- Copyright (C) 2011, 2018, 2022 Stephane Carrez -- Written by Stephane Carrez (Stephane.Carrez@gmail.com) -- -- 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. ----------------------------------------------------------------------- with Ada.Strings.Unbounded; with Util.Properties; -- == Localized date formatting == -- The `Util.Dates.Formats` provides a date formatting and parsing operation similar to the -- Unix `strftime`, `strptime` or the `GNAT.Calendar.Time_IO`. The localization of month -- and day labels is however handled through `Util.Properties.Bundle` (similar to -- the Java world). Unlike `strftime` and `strptime`, this allows to have a multi-threaded -- application that reports dates in several languages. The `GNAT.Calendar.Time_IO` only -- supports English and this is the reason why it is not used here. -- -- The date pattern recognizes the following formats: -- -- | Format | Description | -- | --- | ---------- | -- | %a | The abbreviated weekday name according to the current locale. -- | %A | The full weekday name according to the current locale. -- | %b | The abbreviated month name according to the current locale. -- | %h | Equivalent to %b. (SU) -- | %B | The full month name according to the current locale. -- | %c | The preferred date and time representation for the current locale. -- | %C | The century number (year/100) as a 2-digit integer. (SU) -- | %d | The day of the month as a decimal number (range 01 to 31). -- | %D | Equivalent to %m/%d/%y -- | %e | Like %d, the day of the month as a decimal number, -- | | but a leading zero is replaced by a space. (SU) -- | %F | Equivalent to %Y\-%m\-%d (the ISO 8601 date format). (C99) -- | %G | The ISO 8601 week-based year -- | %H | The hour as a decimal number using a 24-hour clock (range 00 to 23). -- | %I | The hour as a decimal number using a 12-hour clock (range 01 to 12). -- | %j | The day of the year as a decimal number (range 001 to 366). -- | %k | The hour (24 hour clock) as a decimal number (range 0 to 23); -- | %l | The hour (12 hour clock) as a decimal number (range 1 to 12); -- | %m | The month as a decimal number (range 01 to 12). -- | %M | The minute as a decimal number (range 00 to 59). -- | %n | A newline character. (SU) -- | %p | Either "AM" or "PM" -- | %P | Like %p but in lowercase: "am" or "pm" -- | %r | The time in a.m. or p.m. notation. -- | | In the POSIX locale this is equivalent to %I:%M:%S %p. (SU) -- | %R | The time in 24 hour notation (%H:%M). -- | %s | The number of seconds since the Epoch, that is, -- | | since 1970\-01\-01 00:00:00 UTC. (TZ) -- | %S | The second as a decimal number (range 00 to 60). -- | %t | A tab character. (SU) -- | %T | The time in 24 hour notation (%H:%M:%S). (SU) -- | %u | The day of the week as a decimal, range 1 to 7, -- | | Monday being 1. See also %w. (SU) -- | %U | The week number of the current year as a decimal -- | | number, range 00 to 53 -- | %V | The ISO 8601 week number -- | %w | The day of the week as a decimal, range 0 to 6, -- | | Sunday being 0. See also %u. -- | %W | The week number of the current year as a decimal number, -- | | range 00 to 53 -- | %x | The preferred date representation for the current locale -- | | without the time. -- | %X | The preferred time representation for the current locale -- | | without the date. -- | %y | The year as a decimal number without a century (range 00 to 99). -- | %Y | The year as a decimal number including the century. -- | %z | The timezone as hour offset from GMT. -- | %Z | The timezone or name or abbreviation. -- -- The following strftime flags are ignored: -- -- | Format | Description | -- | --- | ---------- | -- | %E | Modifier: use alternative format, see below. (SU) -- | %O | Modifier: use alternative format, see below. (SU) -- -- SU: Single Unix Specification -- C99: C99 standard, POSIX.1-2001 -- -- See strftime (3) and strptime (3) manual page -- -- To format and use the localize date, it is first necessary to get a bundle -- for the `dates` so that date elements are translated into the given locale. -- -- Factory : Util.Properties.Bundles.Loader; -- Bundle : Util.Properties.Bundles.Manager; -- ... -- Load_Bundle (Factory, "dates", "fr", Bundle); -- -- The date is formatted according to the pattern string described above. -- The bundle is used by the formatter to use the day and month names in the -- expected locale. -- -- Date : String := Util.Dates.Formats.Format (Pattern => Pattern, -- Date => Ada.Calendar.Clock, -- Bundle => Bundle); -- -- To parse a date according to a pattern and a localization, the same pattern string -- and bundle can be used and the `Parse` function will return the date in split format. -- -- Result : Date_Record := Util.Dates.Formats.Parse (Date => Date, -- Pattern => Pattern, -- Bundle => Bundle); -- package Util.Dates.Formats is -- Month labels. MONTH_NAME_PREFIX : constant String := "util.month"; -- Day labels. DAY_NAME_PREFIX : constant String := "util.day"; -- Short month/day suffix. SHORT_SUFFIX : constant String := ".short"; -- Long month/day suffix. LONG_SUFFIX : constant String := ".long"; -- The date time pattern name to be used for the %x representation. -- This property name is searched in the bundle to find the localized date time pattern. DATE_TIME_LOCALE_NAME : constant String := "util.datetime.pattern"; -- The default date pattern for %c (English). DATE_TIME_DEFAULT_PATTERN : constant String := "%a %b %_d %T %Y"; -- The date pattern to be used for the %x representation. -- This property name is searched in the bundle to find the localized date pattern. DATE_LOCALE_NAME : constant String := "util.date.pattern"; -- The default date pattern for %x (English). DATE_DEFAULT_PATTERN : constant String := "%m/%d/%y"; -- The time pattern to be used for the %X representation. -- This property name is searched in the bundle to find the localized time pattern. TIME_LOCALE_NAME : constant String := "util.time.pattern"; -- The default time pattern for %X (English). TIME_DEFAULT_PATTERN : constant String := "%T %Y"; AM_NAME : constant String := "util.date.am"; PM_NAME : constant String := "util.date.pm"; AM_DEFAULT : constant String := "AM"; PM_DEFAULT : constant String := "PM"; -- Format the date passed in Date using the date pattern specified in Pattern. -- The date pattern is similar to the Unix strftime operation. -- -- For month and day of week strings, use the resource bundle passed in Bundle. -- Append the formatted date in the Into string. procedure Format (Into : in out Ada.Strings.Unbounded.Unbounded_String; Pattern : in String; Date : in Date_Record; Bundle : in Util.Properties.Manager'Class); -- Format the date passed in Date using the date pattern specified in Pattern. -- For month and day of week strings, use the resource bundle passed in Bundle. -- Append the formatted date in the Into string. procedure Format (Into : in out Ada.Strings.Unbounded.Unbounded_String; Pattern : in String; Date : in Ada.Calendar.Time; Bundle : in Util.Properties.Manager'Class); function Format (Pattern : in String; Date : in Ada.Calendar.Time; Bundle : in Util.Properties.Manager'Class) return String; -- Append the localized month string in the Into string. -- The month string is found in the resource bundle under the name: -- util.month.short -- util.month.long -- If the month string is not found, the month is displayed as a number. procedure Append_Month (Into : in out Ada.Strings.Unbounded.Unbounded_String; Month : in Ada.Calendar.Month_Number; Bundle : in Util.Properties.Manager'Class; Short : in Boolean := True); -- Append the localized month string in the Into string. -- The month string is found in the resource bundle under the name: -- util.month.short -- util.month.long -- If the month string is not found, the month is displayed as a number. procedure Append_Day (Into : in out Ada.Strings.Unbounded.Unbounded_String; Day : in Ada.Calendar.Formatting.Day_Name; Bundle : in Util.Properties.Manager'Class; Short : in Boolean := True); -- Append a number with padding if necessary procedure Append_Number (Into : in out Ada.Strings.Unbounded.Unbounded_String; Value : in Natural; Padding : in Character; Length : in Natural := 2); -- Append the timezone offset procedure Append_Time_Offset (Into : in out Ada.Strings.Unbounded.Unbounded_String; Offset : in Ada.Calendar.Time_Zones.Time_Offset); -- Parse the date according to the pattern and the given locale bundle and -- return the data split record. -- A `Constraint_Error` exception is raised if the date string is not in the correct format. function Parse (Date : in String; Pattern : in String; Bundle : in Util.Properties.Manager'Class) return Date_Record; end Util.Dates.Formats;