2022-01-24 18:37:06 +00:00
/***
Copyright ( C ) 2022 J Reece Wilson ( a / k / a " Reece " ) . All rights reserved .
File : LocaleStrings . cpp
Date : 2022 - 1 - 23
Author : Reece
* * */
# include <Source/RuntimeInternal.hpp>
# include "LocaleStrings.hpp"
namespace Aurora : : Locale
{
AUKN_SYM AuString NumbericLocaleGetDecimal ( )
{
return " . " ; //for.now
}
AUKN_SYM AuString TimeLocaleGetDayChar ( )
{
return " d " ; //for.now
}
AUKN_SYM AuString TimeLocaleS ( )
{
return " s " ;
}
AUKN_SYM AuString TimeLocaleGetMSChar ( )
{
return " ms " ; //for.now
}
static AuString & _TextPrepadZeroIfOne ( AuString & in )
{
if ( in . size ( ) = = 1 ) in . insert ( in . begin ( ) , ' 0 ' ) ;
return in ;
}
static AuString _TextPrepadZeroIfOne ( const AuString & in )
{
AuString ret = in ;
if ( ret . size ( ) = = 1 ) ret . insert ( ret . begin ( ) , ' 0 ' ) ;
return ret ;
}
static AuString _TextPrepadZeroMS ( const AuString & in )
{
AuString ret = in ;
if ( ret . size ( ) = = 1 ) ret . insert ( 0 , " 000 " , 3 ) ;
else if ( ret . size ( ) = = 2 ) ret . insert ( 0 , " 000 " , 2 ) ;
else if ( ret . size ( ) = = 3 ) ret . insert ( 0 , " 000 " , 1 ) ;
while ( ret . size ( ) > 1 & & ret [ ret . size ( ) - 1 ] = = ' 0 ' )
ret . pop_back ( ) ;
return ret ;
}
static AuString _TextPrepadZeroNS ( const AuString & in )
{
AuString ret = in ;
switch ( ret . size ( ) )
{
case 1 : ret . insert ( 0 , " 000000 " , 6 ) ; break ;
case 2 : ret . insert ( 0 , " 000000 " , 5 ) ; break ;
case 3 : ret . insert ( 0 , " 000000 " , 4 ) ; break ;
case 4 : ret . insert ( 0 , " 000000 " , 3 ) ; break ;
case 5 : ret . insert ( 0 , " 000000 " , 2 ) ; break ;
case 6 : ret . insert ( 0 , " 000000 " , 1 ) ; break ;
}
while ( ret . size ( ) > 1 & & ret [ ret . size ( ) - 1 ] = = ' 0 ' )
ret . pop_back ( ) ;
return ret ;
}
AUKN_SYM AuString ConvertMSToTimescale ( AuUInt32 ms )
{
const auto msDiv1000 = ms / 1000 ; // seconds
const auto msDiv1000Mod60 = msDiv1000 % 60 ; // remaining seconds relative to next whole minute
const auto msDiv1000Div60 = msDiv1000 / 60 ; // total minutes
try
{
2022-01-26 00:01:06 +00:00
// This is completely arbitrary
// I feel as though this would do juststice to large and small timescales; with sane formatting, without being too autistic on resolution, and without returning excessively long (^ and localized) strings
// We probably don't need to keep the MS around for more than a minute
2022-01-26 04:22:12 +00:00
// We can use the lengthy MS padding to pad out seconds more into the ballpark of HH:MM:SS
2022-01-26 00:01:06 +00:00
// We can measure months, perhaps years, using mere days. We, and most normies, can comprehend 30/60/90/360/720 without much problem
//
// ! = pad
//
// S!2.MS!4s (01.5000s)
// M!2.S!2 (02:29)
// H!2:M!2:S!2 (01:02:29)
// D!0d H!2:M!2:S!2 (9d 01:02:29)
2022-01-24 18:37:06 +00:00
if ( ms < 1000 )
{
return AuToString ( ms ) + TimeLocaleGetMSChar ( ) ;
}
else if ( ms < ( 1000 * 60 ) )
{
auto s = msDiv1000 ;
auto remMs = ms % 1000 ;
return _TextPrepadZeroIfOne ( AuToString ( s ) ) + NumbericLocaleGetDecimal ( ) + _TextPrepadZeroMS ( AuToString ( remMs ) ) + TimeLocaleS ( ) ;
}
else if ( ms < ( 1000 * 60 * 60 ) )
{
auto m = msDiv1000Div60 ;
auto remS = msDiv1000Mod60 ;
return _TextPrepadZeroIfOne ( AuToString ( m ) ) + " : " + _TextPrepadZeroIfOne ( AuToString ( remS ) ) ;
}
else if ( ms < ( 1000 * 60 * 60 * 24 ) )
{
auto h = msDiv1000Div60 / 60 ;
auto remM = msDiv1000Div60 ;
auto remS = msDiv1000Mod60 ;
return _TextPrepadZeroIfOne ( AuToString ( h ) ) + " : " + _TextPrepadZeroIfOne ( AuToString ( remM ) ) + " : " + _TextPrepadZeroIfOne ( AuToString ( remS ) ) ;
}
else
{
auto d = ( msDiv1000Div60 / 60 / 24 ) ;
auto h = ( msDiv1000Div60 / 60 ) - ( d * 24 ) ;
auto remM = msDiv1000Div60 ;
auto remS = msDiv1000Mod60 ;
return AuToString ( d ) + TimeLocaleGetDayChar ( ) + " " + _TextPrepadZeroIfOne ( AuToString ( h ) ) + " : " + _TextPrepadZeroIfOne ( AuToString ( remM ) ) + " : " + _TextPrepadZeroIfOne ( AuToString ( remS ) ) ;
}
}
catch ( . . . )
{
SysPushErrorGeneric ( " ConvertNSToTimescale failed -> returning empty string " ) ;
return { } ;
}
}
AUKN_SYM AuString ConvertNSToTimescale ( AuUInt64 ns )
{
try
{
if ( ns < AuUInt64 ( 1000000000 ) )
{
const auto ms = ns / 1000000 ;
const auto remNs = ns % 1000000 ;
return _TextPrepadZeroMS ( AuToString ( ms ) ) + NumbericLocaleGetDecimal ( ) + _TextPrepadZeroNS ( AuToString ( remNs ) ) + TimeLocaleGetMSChar ( ) ;
}
else
{
return ConvertMSToTimescale ( ns / AuUInt64 ( 1000000000 ) ) ;
}
}
catch ( . . . )
{
SysPushErrorGeneric ( " ConvertNSToTimescale failed -> returning empty string " ) ;
return { } ;
}
}
AUKN_SYM AuString TimeDateToString ( const Time : : tm & time )
{
try
{
bool simple = time . tm_mday = = 0 & & time . tm_mon = = 0 & & time . tm_year = = 0 ;
if ( simple )
{
return fmt : : format ( " {:02}-{:02}-{:02} " , time . tm_hour , time . tm_min , time . tm_sec ) ;
}
else
{
// Hard-code ISO-8601 locale because, the larders locale doesn't make any sense whatsoever, and east asia has the right idea
// EU users and burgers seethe... we normalize one standard to disambiguate this shit
return fmt : : format ( " {:{:04}-{:02}-{:02} {:02}-{:02}-{:02}} " , time . tm_year + 1900 , time . tm_mon + 1 , time . tm_mday , time . tm_hour , time . tm_min , time . tm_sec ) ;
}
}
catch ( . . . )
{
SysPushErrorGeneric ( " TimeDateToString failed -> returning empty string " ) ;
return { } ;
}
}
AUKN_SYM AuString TimeDateToISO8601 ( const Time : : tm & time , AuTime : : ETimezoneShift shift )
{
try
{
AuString tz { } ;
auto tnorm = AuTime : : NormalizeCivilTimezone ( time , shift ) ;
return fmt : : format ( " {:04}-{:02}-{:02}T{:02}-{:02}-{:02}Z " ,
tnorm . tm_year + 1900 , tnorm . tm_mon + 1 , tnorm . tm_mday ,
tnorm . tm_hour , tnorm . tm_min , tnorm . tm_sec ) ;
}
catch ( . . . )
{
SysPushErrorGeneric ( " TimeDateToISO8601 failed -> returning empty string " ) ;
return { } ;
}
}
}