initial commit
This commit is contained in:
538
TIME_FORMAT_RESEARCH.md
Normal file
538
TIME_FORMAT_RESEARCH.md
Normal file
@@ -0,0 +1,538 @@
|
||||
# Time Format Patterns - Cross-System Comparison
|
||||
|
||||
## Overview
|
||||
|
||||
This document provides a comprehensive comparison of time format patterns across different programming languages and systems. This research will help inform the design of a widely-recognized, human-readable time format.
|
||||
|
||||
---
|
||||
|
||||
## 1. Unicode LDML (Locale Data Markup Language)
|
||||
|
||||
**Used by:** ICU, Java, Swift, JavaScript (Intl), and many internationalization libraries
|
||||
|
||||
### Key Characteristics
|
||||
- Single letters represent minimal/numeric forms
|
||||
- Repeated letters increase width or change format type
|
||||
- Case-sensitive (different meanings for upper/lower case)
|
||||
- Canonical order matters for skeletons
|
||||
|
||||
### Format Tokens
|
||||
|
||||
| Element | Token | Examples | Notes |
|
||||
|---------|-------|----------|-------|
|
||||
| **Year** |
|
||||
| 4-digit year | `yyyy` or `y` | 2024, 0070 | `y` adapts to context |
|
||||
| 2-digit year | `yy` | 24, 70 | 00-99 |
|
||||
| **Month** |
|
||||
| Numeric, no zero | `M` | 1, 12 | 1-12 |
|
||||
| Numeric, zero-padded | `MM` | 01, 12 | 01-12 |
|
||||
| Abbreviated name | `MMM` | Jan, Dec | Locale-specific |
|
||||
| Full name | `MMMM` | January, December | Locale-specific |
|
||||
| Stand-alone abbrev | `LLL` | Jan, Dec | Nominative form |
|
||||
| Stand-alone full | `LLLL` | January, December | Nominative form |
|
||||
| **Day of Month** |
|
||||
| Numeric, no zero | `d` | 1, 31 | 1-31 |
|
||||
| Numeric, zero-padded | `dd` | 01, 31 | 01-31 |
|
||||
| **Weekday** |
|
||||
| Abbreviated | `EEE` | Mon, Fri | Locale-specific |
|
||||
| Full name | `EEEE` | Monday, Friday | Locale-specific |
|
||||
| Narrow | `EEEEE` | M, F | Single character |
|
||||
| Short | `EEEEEE` | Mo, Fr | Between abbrev & narrow |
|
||||
| **Hour (12-hour)** |
|
||||
| No zero (1-12) | `h` | 1, 12 | Requires AM/PM |
|
||||
| Zero-padded (01-12) | `hh` | 01, 12 | Requires AM/PM |
|
||||
| **Hour (24-hour)** |
|
||||
| No zero (0-23) | `H` | 0, 23 | |
|
||||
| Zero-padded (00-23) | `HH` | 00, 23 | |
|
||||
| **Minute** |
|
||||
| No zero | `m` | 0, 59 | 0-59 |
|
||||
| Zero-padded | `mm` | 00, 59 | 00-59 |
|
||||
| **Second** |
|
||||
| No zero | `s` | 0, 59 | 0-59 |
|
||||
| Zero-padded | `ss` | 00, 59 | 00-59 |
|
||||
| **Fractional Seconds** |
|
||||
| Milliseconds | `SSS` | 000, 999 | Always 3 digits |
|
||||
| Variable precision | `S` to `SSSSSSSSS` | 0 to 9 digits | Fractional precision |
|
||||
| **AM/PM** |
|
||||
| Period | `a` | AM, PM | Locale-specific |
|
||||
| Period, narrow | `aaaaa` | a, p | Single character |
|
||||
| Day period (flexible) | `b` | at night, in the morning | Locale-specific |
|
||||
| Day period (specific) | `B` | noon, midnight | Locale-specific |
|
||||
| **Timezone** |
|
||||
| ISO offset | `Z` to `ZZZZZ` | -0800, -08:00, Z | Various formats |
|
||||
| Localized GMT | `O` to `OOOO` | GMT-8, GMT-08:00 | |
|
||||
| Generic non-location | `v` | PT | Short form |
|
||||
| Generic non-location | `vvvv` | Pacific Time | Long form |
|
||||
| Specific non-location | `z` | PST | Short form |
|
||||
| Specific non-location | `zzzz` | Pacific Standard Time | Long form |
|
||||
|
||||
### Common Pattern Examples
|
||||
- `yyyy-MM-dd` → 2024-02-08
|
||||
- `MMM d, yyyy` → Feb 8, 2024
|
||||
- `EEEE, MMMM d, yyyy` → Thursday, February 8, 2024
|
||||
- `h:mm a` → 3:45 PM
|
||||
- `HH:mm:ss` → 15:45:30
|
||||
- `yyyy-MM-dd'T'HH:mm:ss` → 2024-02-08T15:45:30
|
||||
|
||||
---
|
||||
|
||||
## 2. strftime (C, Python, Ruby, PHP, etc.)
|
||||
|
||||
**Used by:** C, C++, Python, Ruby, PHP, Perl, Unix/Linux systems
|
||||
|
||||
### Key Characteristics
|
||||
- All format codes start with `%`
|
||||
- Single character codes (case-sensitive)
|
||||
- Platform-dependent for some codes
|
||||
- Locale-aware variants with `E` and `O` modifiers
|
||||
|
||||
### Format Codes
|
||||
|
||||
| Element | Code | Examples | Notes |
|
||||
|---------|------|----------|-------|
|
||||
| **Year** |
|
||||
| 4-digit year | `%Y` | 2024, 0070 | |
|
||||
| 2-digit year | `%y` | 24, 70 | 00-99 |
|
||||
| Century | `%C` | 20 | First 2 digits |
|
||||
| **Month** |
|
||||
| Numeric, zero-padded | `%m` | 01, 12 | 01-12 |
|
||||
| Abbreviated name | `%b` or `%h` | Jan, Dec | Locale-specific |
|
||||
| Full name | `%B` | January, December | Locale-specific |
|
||||
| **Day of Month** |
|
||||
| Zero-padded | `%d` | 01, 31 | 01-31 |
|
||||
| Space-padded | `%e` | " 1", "31" | 1-31 with space |
|
||||
| **Weekday** |
|
||||
| Abbreviated | `%a` | Mon, Fri | Locale-specific |
|
||||
| Full name | `%A` | Monday, Friday | Locale-specific |
|
||||
| Numeric (0-6) | `%w` | 0, 6 | Sunday = 0 |
|
||||
| Numeric (1-7) | `%u` | 1, 7 | Monday = 1 |
|
||||
| **Hour (12-hour)** |
|
||||
| Zero-padded | `%I` | 01, 12 | 01-12, requires AM/PM |
|
||||
| **Hour (24-hour)** |
|
||||
| Zero-padded | `%H` | 00, 23 | 00-23 |
|
||||
| Space-padded | `%k` | " 0", "23" | 0-23 with space |
|
||||
| **Minute** |
|
||||
| Zero-padded | `%M` | 00, 59 | 00-59 |
|
||||
| **Second** |
|
||||
| Zero-padded | `%S` | 00, 59 | 00-59 |
|
||||
| **Fractional Seconds** |
|
||||
| Microseconds | `%f` | 000000, 999999 | Python-specific, 6 digits |
|
||||
| **AM/PM** |
|
||||
| Period | `%p` | AM, PM | Locale-specific |
|
||||
| Period lowercase | `%P` | am, pm | GNU extension |
|
||||
| **Timezone** |
|
||||
| Name or abbreviation | `%Z` | PST, EST | Platform-dependent |
|
||||
| Offset | `%z` | -0800, +0530 | ±HHMM format |
|
||||
| **Composite Formats** |
|
||||
| Date (MM/DD/YY) | `%D` | 02/08/24 | Equivalent to %m/%d/%y |
|
||||
| ISO date | `%F` | 2024-02-08 | Equivalent to %Y-%m-%d |
|
||||
| 12-hour time | `%r` | 03:45:30 PM | Locale-specific |
|
||||
| 24-hour time (HH:MM) | `%R` | 15:45 | Equivalent to %H:%M |
|
||||
| Time with seconds | `%T` | 15:45:30 | Equivalent to %H:%M:%S |
|
||||
| Date and time | `%c` | Thu Feb 8 15:45:30 2024 | Locale-specific |
|
||||
|
||||
### Common Pattern Examples
|
||||
- `%Y-%m-%d` → 2024-02-08
|
||||
- `%b %d, %Y` → Feb 08, 2024
|
||||
- `%A, %B %d, %Y` → Thursday, February 08, 2024
|
||||
- `%I:%M %p` → 03:45 PM
|
||||
- `%H:%M:%S` → 15:45:30
|
||||
- `%Y-%m-%dT%H:%M:%S` → 2024-02-08T15:45:30
|
||||
|
||||
---
|
||||
|
||||
## 3. Moment.js / Day.js (JavaScript)
|
||||
|
||||
**Used by:** Moment.js, Day.js (legacy JavaScript libraries)
|
||||
|
||||
### Key Characteristics
|
||||
- No special prefix character
|
||||
- Case-sensitive
|
||||
- Repetition changes format
|
||||
- Inspired by PHP date() function
|
||||
|
||||
### Format Tokens
|
||||
|
||||
| Element | Token | Examples | Notes |
|
||||
|---------|-------|----------|-------|
|
||||
| **Year** |
|
||||
| 4-digit year | `YYYY` | 2024, 0070 | |
|
||||
| 2-digit year | `YY` | 24, 70 | 00-99 |
|
||||
| **Month** |
|
||||
| Numeric, no zero | `M` | 1, 12 | 1-12 |
|
||||
| Numeric, zero-padded | `MM` | 01, 12 | 01-12 |
|
||||
| Abbreviated name | `MMM` | Jan, Dec | |
|
||||
| Full name | `MMMM` | January, December | |
|
||||
| **Day of Month** |
|
||||
| Numeric, no zero | `D` | 1, 31 | 1-31 |
|
||||
| Numeric, zero-padded | `DD` | 01, 31 | 01-31 |
|
||||
| Ordinal | `Do` | 1st, 31st | With suffix |
|
||||
| **Weekday** |
|
||||
| Abbreviated | `ddd` | Mon, Fri | |
|
||||
| Full name | `dddd` | Monday, Friday | |
|
||||
| Min (2 chars) | `dd` | Mo, Fr | |
|
||||
| Numeric (0-6) | `d` | 0, 6 | Sunday = 0 |
|
||||
| **Hour (12-hour)** |
|
||||
| No zero (1-12) | `h` | 1, 12 | Requires A or a |
|
||||
| Zero-padded (01-12) | `hh` | 01, 12 | Requires A or a |
|
||||
| **Hour (24-hour)** |
|
||||
| No zero (0-23) | `H` | 0, 23 | |
|
||||
| Zero-padded (00-23) | `HH` | 00, 23 | |
|
||||
| **Minute** |
|
||||
| No zero | `m` | 0, 59 | 0-59 |
|
||||
| Zero-padded | `mm` | 00, 59 | 00-59 |
|
||||
| **Second** |
|
||||
| No zero | `s` | 0, 59 | 0-59 |
|
||||
| Zero-padded | `ss` | 00, 59 | 00-59 |
|
||||
| **Fractional Seconds** |
|
||||
| 1-3 digits | `S`, `SS`, `SSS` | 0, 00, 000 | Tenths, hundredths, ms |
|
||||
| Up to 9 digits | `SSSS` to `SSSSSSSSS` | Variable | Extended precision |
|
||||
| **AM/PM** |
|
||||
| Lowercase | `a` | am, pm | |
|
||||
| Uppercase | `A` | AM, PM | |
|
||||
| **Timezone** |
|
||||
| Offset | `Z` | -08:00, +05:30 | With colon |
|
||||
| Compact offset | `ZZ` | -0800, +0530 | Without colon |
|
||||
|
||||
### Common Pattern Examples
|
||||
- `YYYY-MM-DD` → 2024-02-08
|
||||
- `MMM D, YYYY` → Feb 8, 2024
|
||||
- `dddd, MMMM D, YYYY` → Thursday, February 8, 2024
|
||||
- `h:mm A` → 3:45 PM
|
||||
- `HH:mm:ss` → 15:45:30
|
||||
- `YYYY-MM-DDTHH:mm:ss` → 2024-02-08T15:45:30
|
||||
|
||||
---
|
||||
|
||||
## 4. date-fns (Modern JavaScript)
|
||||
|
||||
**Used by:** date-fns library
|
||||
|
||||
### Key Characteristics
|
||||
- Based on Unicode LDML tokens
|
||||
- More standardized than Moment.js
|
||||
- Case-sensitive
|
||||
- Uses escape sequences for literals
|
||||
|
||||
### Format Tokens
|
||||
|
||||
*date-fns uses Unicode LDML tokens (see Section 1) with some differences:*
|
||||
|
||||
| Element | Token | Examples | Notes |
|
||||
|---------|-------|----------|-------|
|
||||
| **Year** |
|
||||
| Extended year | `uuuu` | 2024, -0001 | Recommended over yyyy |
|
||||
| Calendar year | `yyyy` | 2024 | Use uuuu instead |
|
||||
| 2-digit year | `yy` or `uu` | 24 | |
|
||||
| **Month** | | | Same as LDML |
|
||||
| **Day** |
|
||||
| Day of month | `d`, `do`, `dd` | 1, 1st, 01 | |
|
||||
| Day of year | `D`, `Do`, `DD`, `DDD` | 1, 1st, 01, 001 | |
|
||||
| **Week** |
|
||||
| Local week | `w`, `wo`, `ww` | 1, 1st, 01 | |
|
||||
| ISO week | `I`, `Io`, `II` | 1, 1st, 01 | |
|
||||
| **Weekday** |
|
||||
| Short | `eee`, `eeeee` | Mon, M | Locale day |
|
||||
| Long | `eeee`, `eeeeee` | Monday, Mo | Locale day |
|
||||
| ISO | `i`, `io`, `iii`, `iiii`, `iiiii`, `iiiiii` | 1, 1st, Mon, Monday, M, Mo | |
|
||||
| **Hour, Minute, Second** | | | Same as LDML |
|
||||
| **AM/PM** | | | Same as LDML |
|
||||
| **Timezone** | | | Extended LDML support |
|
||||
|
||||
### Common Pattern Examples
|
||||
- `yyyy-MM-dd` → 2024-02-08
|
||||
- `MMM d, yyyy` → Feb 8, 2024
|
||||
- `EEEE, MMMM d, yyyy` → Thursday, February 8, 2024
|
||||
- `h:mm a` → 3:45 PM
|
||||
- `HH:mm:ss` → 15:45:30
|
||||
|
||||
---
|
||||
|
||||
## 5. .NET DateTime Formats
|
||||
|
||||
**Used by:** C#, F#, VB.NET, .NET platform
|
||||
|
||||
### Key Characteristics
|
||||
- Single character codes (case-sensitive)
|
||||
- Can use multiple characters for wider format
|
||||
- Custom format strings combine individual specifiers
|
||||
- Standard format strings (single character) produce locale-specific output
|
||||
|
||||
### Format Specifiers
|
||||
|
||||
| Element | Specifier | Examples | Notes |
|
||||
|---------|-----------|----------|-------|
|
||||
| **Year** |
|
||||
| 1-2 digit year | `y` | 8, 24 | Minimum digits |
|
||||
| 2-digit year | `yy` | 08, 24 | 00-99 |
|
||||
| 3-digit year | `yyy` | 008, 024 | Minimum 3 digits |
|
||||
| 4-digit year | `yyyy` | 0008, 2024 | |
|
||||
| 5-digit year | `yyyyy` | 00008, 02024 | |
|
||||
| **Month** |
|
||||
| Numeric, no zero | `M` | 1, 12 | 1-12 |
|
||||
| Numeric, zero-padded | `MM` | 01, 12 | 01-12 |
|
||||
| Abbreviated name | `MMM` | Jan, Dec | Locale-specific |
|
||||
| Full name | `MMMM` | January, December | Locale-specific |
|
||||
| **Day of Month** |
|
||||
| Numeric, no zero | `d` | 1, 31 | 1-31 |
|
||||
| Numeric, zero-padded | `dd` | 01, 31 | 01-31 |
|
||||
| **Weekday** |
|
||||
| Abbreviated | `ddd` | Mon, Fri | Locale-specific |
|
||||
| Full name | `dddd` | Monday, Friday | Locale-specific |
|
||||
| **Hour (12-hour)** |
|
||||
| No zero (1-12) | `h` | 1, 12 | Requires tt or t |
|
||||
| Zero-padded (01-12) | `hh` | 01, 12 | Requires tt or t |
|
||||
| **Hour (24-hour)** |
|
||||
| No zero (0-23) | `H` | 0, 23 | |
|
||||
| Zero-padded (00-23) | `HH` | 00, 23 | |
|
||||
| **Minute** |
|
||||
| No zero | `m` | 0, 59 | 0-59 |
|
||||
| Zero-padded | `mm` | 00, 59 | 00-59 |
|
||||
| **Second** |
|
||||
| No zero | `s` | 0, 59 | 0-59 |
|
||||
| Zero-padded | `ss` | 00, 59 | 00-59 |
|
||||
| **Fractional Seconds** |
|
||||
| Tenths | `f` | 0-9 | Always shown |
|
||||
| Hundredths | `ff` | 00-99 | Always shown |
|
||||
| Milliseconds | `fff` | 000-999 | Always shown |
|
||||
| Optional tenths | `F` | 0-9 or nothing | Not shown if zero |
|
||||
| Optional hundredths | `FF` | 00-99 or nothing | Not shown if zero |
|
||||
| Optional milliseconds | `FFF` | 000-999 or nothing | Not shown if zero |
|
||||
| Up to 7 digits | `fffffff`, `FFFFFFF` | Nanosecond precision | |
|
||||
| **AM/PM** |
|
||||
| First char | `t` | A, P | Locale-specific |
|
||||
| Full designator | `tt` | AM, PM | Locale-specific |
|
||||
| **Timezone** |
|
||||
| Hours offset | `z` | -8, +5 | No leading zero |
|
||||
| Hours offset padded | `zz` | -08, +05 | With leading zero |
|
||||
| Full offset | `zzz` | -08:00, +05:30 | Hours and minutes |
|
||||
| **Other** |
|
||||
| Era | `g` or `gg` | A.D. | Period/era |
|
||||
| Time separator | `:` | : | Locale-specific |
|
||||
| Date separator | `/` | / | Locale-specific |
|
||||
|
||||
### Standard Format Strings
|
||||
- `d` - Short date pattern (MM/dd/yyyy)
|
||||
- `D` - Long date pattern (dddd, MMMM dd, yyyy)
|
||||
- `t` - Short time pattern (h:mm tt)
|
||||
- `T` - Long time pattern (h:mm:ss tt)
|
||||
- `f` - Full date/time short (dddd, MMMM dd, yyyy h:mm tt)
|
||||
- `F` - Full date/time long (dddd, MMMM dd, yyyy h:mm:ss tt)
|
||||
- `g` - General short (M/d/yyyy h:mm tt)
|
||||
- `G` - General long (M/d/yyyy h:mm:ss tt)
|
||||
- `o` - ISO 8601 (yyyy-MM-ddTHH:mm:ss.fffffffK)
|
||||
- `s` - Sortable (yyyy-MM-ddTHH:mm:ss)
|
||||
|
||||
### Common Pattern Examples
|
||||
- `yyyy-MM-dd` → 2024-02-08
|
||||
- `MMM d, yyyy` → Feb 8, 2024
|
||||
- `dddd, MMMM d, yyyy` → Thursday, February 8, 2024
|
||||
- `h:mm tt` → 3:45 PM
|
||||
- `HH:mm:ss` → 15:45:30
|
||||
- `yyyy-MM-ddTHH:mm:ss` → 2024-02-08T15:45:30
|
||||
|
||||
---
|
||||
|
||||
## 6. ISO 8601 Standard
|
||||
|
||||
**International Standard for date and time representation**
|
||||
|
||||
### Key Characteristics
|
||||
- Designed for unambiguous machine-readable formats
|
||||
- Always uses Gregorian calendar
|
||||
- Year-month-day order (largest to smallest units)
|
||||
- Uses T as date/time separator
|
||||
- Uses Z to denote UTC
|
||||
|
||||
### Standard Representations
|
||||
|
||||
| Format | Pattern | Example | Notes |
|
||||
|--------|---------|---------|-------|
|
||||
| **Date** |
|
||||
| Calendar date | `YYYY-MM-DD` | 2024-02-08 | Extended format |
|
||||
| Calendar date | `YYYYMMDD` | 20240208 | Basic format |
|
||||
| Week date | `YYYY-Www-D` | 2024-W06-4 | Week 6, day 4 |
|
||||
| Week date | `YYYYWwwD` | 2024W064 | Basic format |
|
||||
| Ordinal date | `YYYY-DDD` | 2024-039 | Day 39 of year |
|
||||
| Ordinal date | `YYYYDDD` | 2024039 | Basic format |
|
||||
| Year and month | `YYYY-MM` | 2024-02 | |
|
||||
| Year only | `YYYY` | 2024 | |
|
||||
| **Time** |
|
||||
| Hours and minutes | `hh:mm` | 15:45 | Extended format |
|
||||
| Hours and minutes | `hhmm` | 1545 | Basic format |
|
||||
| Hours, min, sec | `hh:mm:ss` | 15:45:30 | Extended format |
|
||||
| Hours, min, sec | `hhmmss` | 154530 | Basic format |
|
||||
| With fractional sec | `hh:mm:ss.sss` | 15:45:30.123 | Variable precision |
|
||||
| **DateTime** |
|
||||
| Combined | `YYYY-MM-DDThh:mm:ss` | 2024-02-08T15:45:30 | T separator |
|
||||
| Combined basic | `YYYYMMDDThhmmss` | 20240208T154530 | No separators |
|
||||
| **Timezone** |
|
||||
| UTC indicator | `Z` | 2024-02-08T15:45:30Z | Zulu time |
|
||||
| Offset | `±hh:mm` | 2024-02-08T15:45:30-08:00 | Extended format |
|
||||
| Offset | `±hhmm` | 2024-02-08T15:45:30-0800 | Basic format |
|
||||
| Offset | `±hh` | 2024-02-08T15:45:30-08 | Hours only |
|
||||
|
||||
### Common ISO 8601 Examples
|
||||
- `2024-02-08` (Date only)
|
||||
- `15:45:30` (Time only)
|
||||
- `2024-02-08T15:45:30` (Local datetime)
|
||||
- `2024-02-08T15:45:30Z` (UTC datetime)
|
||||
- `2024-02-08T15:45:30-08:00` (With timezone offset)
|
||||
- `2024-W06-4` (Week date: year 2024, week 6, Thursday)
|
||||
|
||||
---
|
||||
|
||||
## Cross-System Comparison Table
|
||||
|
||||
### Year Formats
|
||||
|
||||
| Format | LDML | strftime | Moment | date-fns | .NET | ISO 8601 |
|
||||
|--------|------|----------|--------|----------|------|----------|
|
||||
| 4-digit | `yyyy` | `%Y` | `YYYY` | `yyyy` | `yyyy` | `YYYY` |
|
||||
| 2-digit | `yy` | `%y` | `YY` | `yy` | `yy` | `YY` |
|
||||
|
||||
### Month Formats
|
||||
|
||||
| Format | LDML | strftime | Moment | date-fns | .NET | ISO 8601 |
|
||||
|--------|------|----------|--------|----------|------|----------|
|
||||
| Numeric no zero | `M` | - | `M` | `M` | `M` | - |
|
||||
| Numeric zero-pad | `MM` | `%m` | `MM` | `MM` | `MM` | `MM` |
|
||||
| Abbreviated name | `MMM` | `%b` | `MMM` | `MMM` | `MMM` | - |
|
||||
| Full name | `MMMM` | `%B` | `MMMM` | `MMMM` | `MMMM` | - |
|
||||
|
||||
### Day Formats
|
||||
|
||||
| Format | LDML | strftime | Moment | date-fns | .NET | ISO 8601 |
|
||||
|--------|------|----------|--------|----------|------|----------|
|
||||
| Numeric no zero | `d` | - | `D` | `d` | `d` | - |
|
||||
| Numeric zero-pad | `dd` | `%d` | `DD` | `dd` | `dd` | `DD` |
|
||||
| Abbreviated weekday | `EEE` | `%a` | `ddd` | `eee` | `ddd` | - |
|
||||
| Full weekday | `EEEE` | `%A` | `dddd` | `eeee` | `dddd` | - |
|
||||
|
||||
### Hour Formats (12-hour)
|
||||
|
||||
| Format | LDML | strftime | Moment | date-fns | .NET | ISO 8601 |
|
||||
|--------|------|----------|--------|----------|------|----------|
|
||||
| No zero (1-12) | `h` | - | `h` | `h` | `h` | - |
|
||||
| Zero-pad (01-12) | `hh` | `%I` | `hh` | `hh` | `hh` | - |
|
||||
|
||||
### Hour Formats (24-hour)
|
||||
|
||||
| Format | LDML | strftime | Moment | date-fns | .NET | ISO 8601 |
|
||||
|--------|------|----------|--------|----------|------|----------|
|
||||
| No zero (0-23) | `H` | - | `H` | `H` | `H` | - |
|
||||
| Zero-pad (00-23) | `HH` | `%H` | `HH` | `HH` | `HH` | `hh` |
|
||||
|
||||
### Minute/Second Formats
|
||||
|
||||
| Format | LDML | strftime | Moment | date-fns | .NET | ISO 8601 |
|
||||
|--------|------|----------|--------|----------|------|----------|
|
||||
| Minutes no zero | `m` | - | `m` | `m` | `m` | - |
|
||||
| Minutes zero-pad | `mm` | `%M` | `mm` | `mm` | `mm` | `mm` |
|
||||
| Seconds no zero | `s` | - | `s` | `s` | `s` | - |
|
||||
| Seconds zero-pad | `ss` | `%S` | `ss` | `ss` | `ss` | `ss` |
|
||||
|
||||
### AM/PM Indicators
|
||||
|
||||
| Format | LDML | strftime | Moment | date-fns | .NET | ISO 8601 |
|
||||
|--------|------|----------|--------|----------|------|----------|
|
||||
| Uppercase | `a` | `%p` | `A` | `a` | `tt` | N/A |
|
||||
| Lowercase | `aaaaa` | `%P`* | `a` | `aaa` | - | N/A |
|
||||
| First char only | - | - | - | - | `t` | N/A |
|
||||
|
||||
*GNU extension, not POSIX standard
|
||||
|
||||
### Timezone Formats
|
||||
|
||||
| Format | LDML | strftime | Moment | date-fns | .NET | ISO 8601 |
|
||||
|--------|------|----------|--------|----------|------|----------|
|
||||
| Offset with colon | `ZZZZZ` or `XXXXX` | - | `Z` | `XXX` | `zzz` | `±hh:mm` |
|
||||
| Offset no colon | `ZZZ` or `XX` | `%z` | `ZZ` | `XX` | - | `±hhmm` |
|
||||
| UTC indicator | - | - | - | `X` | - | `Z` |
|
||||
| Named timezone | `z`, `zzzz` | `%Z` | - | - | - | N/A |
|
||||
|
||||
---
|
||||
|
||||
## Recommendations for Human-Readable Format
|
||||
|
||||
Based on this research, here are recommendations for a widely-recognized human-readable format:
|
||||
|
||||
### Most Universal Patterns
|
||||
|
||||
1. **Date Only - ISO 8601 style (MOST UNIVERSAL)**
|
||||
- Pattern: `YYYY-MM-DD`
|
||||
- Example: `2024-02-08`
|
||||
- Recognized by: ALL systems
|
||||
- Pros: Unambiguous, sortable, internationally recognized
|
||||
- Cons: Less readable for some English speakers
|
||||
|
||||
2. **Date Only - Text month**
|
||||
- Pattern: `MMM DD, YYYY` or `DD MMM YYYY`
|
||||
- Example: `Feb 08, 2024` or `08 Feb 2024`
|
||||
- Recognized by: All major systems (with slight variations)
|
||||
- Pros: Very readable, avoids MM/DD vs DD/MM confusion
|
||||
- Cons: Not sortable, locale-dependent
|
||||
|
||||
3. **Time Only - 24-hour (MOST UNIVERSAL)**
|
||||
- Pattern: `HH:mm:ss`
|
||||
- Example: `15:45:30`
|
||||
- Recognized by: ALL systems
|
||||
- Pros: Unambiguous, no AM/PM needed
|
||||
- Cons: Some users prefer 12-hour format
|
||||
|
||||
4. **Time Only - 12-hour**
|
||||
- Pattern: `hh:mm:ss AM` or `h:mm:ss a`
|
||||
- Example: `03:45:30 PM`
|
||||
- Recognized by: All major systems (with variations)
|
||||
- Pros: Familiar to many users
|
||||
- Cons: Requires AM/PM designator
|
||||
|
||||
5. **Full DateTime - ISO 8601 (MOST UNIVERSAL)**
|
||||
- Pattern: `YYYY-MM-DDTHH:mm:ss`
|
||||
- Example: `2024-02-08T15:45:30`
|
||||
- Recognized by: ALL systems
|
||||
- Pros: Unambiguous, sortable, international standard
|
||||
- Cons: T separator less readable
|
||||
|
||||
6. **Full DateTime - Human-readable**
|
||||
- Pattern: `MMMM DD, YYYY HH:mm:ss` or `DD MMMM YYYY HH:mm:ss`
|
||||
- Example: `February 08, 2024 15:45:30`
|
||||
- Recognized by: All major systems (with slight variations)
|
||||
- Pros: Very readable
|
||||
- Cons: Verbose, locale-dependent month names
|
||||
|
||||
### Token Compatibility Summary
|
||||
|
||||
**Highest Compatibility (work in 5-6 systems):**
|
||||
- `yyyy`/`YYYY` - 4-digit year
|
||||
- `MM` - 2-digit month (zero-padded)
|
||||
- `dd`/`DD` - 2-digit day (zero-padded)
|
||||
- `HH` - 24-hour time (zero-padded)
|
||||
- `mm` - minutes (zero-padded)
|
||||
- `ss` - seconds (zero-padded)
|
||||
|
||||
**High Compatibility (work in 4-5 systems):**
|
||||
- `MMM` - Abbreviated month name
|
||||
- `MMMM` - Full month name
|
||||
- `hh` - 12-hour time (zero-padded)
|
||||
- `a`/`A`/`tt` - AM/PM (varies by system)
|
||||
|
||||
**Moderate Compatibility:**
|
||||
- `EEE`/`ddd` - Abbreviated weekday
|
||||
- `EEEE`/`dddd` - Full weekday
|
||||
- Single-letter tokens (no zero padding) - variable support
|
||||
|
||||
### Recommended Format for timefmt Project
|
||||
|
||||
For maximum compatibility and readability, consider:
|
||||
|
||||
1. **For machine-readable output**: `YYYY-MM-DD HH:mm:ss` (ISO 8601 without T)
|
||||
2. **For human-readable output**: `MMM DD, YYYY HH:mm:ss` (e.g., "Feb 08, 2024 15:45:30")
|
||||
3. **For compact output**: `YYYY-MM-DD HH:mm` (omit seconds if not needed)
|
||||
|
||||
These formats:
|
||||
- Avoid MM/DD vs DD/MM confusion
|
||||
- Don't require AM/PM logic
|
||||
- Use widely recognized token patterns
|
||||
- Are unambiguous across cultures
|
||||
- Balance readability with precision
|
||||
Reference in New Issue
Block a user