Possible problem with ISO 8601 week number and year number
xotmatrix opened this issue · 2 comments
xotmatrix commented
re: date_format()
This was a pain in the neck to originally research and code until I realized that GM did most of the work already with its week number (which appeared to be ISO 8601 compliant). I saw an example tonight that may show ISO 8601 week numbers and year numbers are not being calculated corrected here. Need to do some more research.
xotmatrix commented
This continues to be a problem in GMS2.3 and is still being investigated.
Here also is an early version of this function written in the GM6 days with a complicated ISO 8601 week calculation. I don't know if it worked right.
/*
** Usage:
** date_format(format,datetime)
**
** Arguments:
** format string controlling date formatting
** datetime date-time value (optional)
**
** Returns:
** a string formatted according to the given format string
** using the given date-time value or the current local time
** if no date-time is given
**
** Day format characters:
** d - day of the month, 2 digits with leading zeros; 01 through 31
** D - day of the week, textual, 3 letters; Fri
** j - day of the month without leading zeros; 1 through 31
** l - day of the week, textual, long; Friday
** N - ISO 8601 day number of the week; 1 (Monday) through 7 (Sunday)
** S - English ordinal suffix, textual, 2 characters; st, nd, rd, th
** w - day of the week, numeric, 0 (Sunday) through 6 (Saturday)
** z - day of the year (starting from zero); 0 through 365
**
** Week format characters:
** W - ISO 8601 week number of year, weeks starting on Monday; 42
**
** Month format characters:
** F - month, textual, long; January
** m - month; 01 through 12
** M - month, textual, 3 letters; Jan
** n - month without leading zeros; 1 through 12
** t - number of days in the given month; 28 through 31
**
** Year format characters:
** L - whether it is a leap year; 0 or 1
** o - ISO 8601 year, like Y unless ISO week belongs to prev or next year; 2008
** Y - year, 4 digits; 1999
** y - year, 2 digits; 99
**
** Time format characters:
** a - lowercase Ante meridiem and Post meridiem; am or pm
** A - uppercase Ante meridiem and Post meridiem; AM or PM
** B - Swatch Internet time; 000 through 999
** g - hour, 12-hour format without leading zeros; 1 through 12
** G - hour, 24-hour format without leading zeros; 0 through 23
** h - hour, 12-hour format; 01 through 12
** H - hour, 24-hour format; 00 through 23
** i - minutes, with leading zero; 00 through 59
** s - seconds, with leading zero; 00 through 59
**
** Full Date/Time format characters:
** c - ISO 8601 date
** r - RFC 2822 formatted data
** U - seconds since the Unix epoch
**
** \ - escape letters which should be literal, not interpreted
**
** Exaples:
** date_format("l jS of F Y h:i:s A") == "Sunday 4th of May 2008 05:45:34 PM"
** date_format('\I\t \i\s \t\h\e zS \d\a\y.') == "It is the 124th day."
**
** GMLscripts.com
*/
{
var str,dat,out,day,month,year,weekday,second,minute,hour24,hour12,i,c;
str = argument0;
dat = argument1;
out = "";
if (dat == 0) dat = date_current_datetime();
day = date_get_day(dat);
month = date_get_month(dat);
year = date_get_year(dat);
weekday = date_get_weekday(dat);
second = date_get_second(dat);
minute = date_get_minute(dat);
hour24 = date_get_hour(dat);
hour12 = ((hour24+23) mod 12)+1;
for (i=1; i<=string_length(str); i+=1) {
c = string_char_at(str,i);
switch (c) {
case "F":
switch (month) {
case 1: out += "January"; break;
case 2: out += "February"; break;
case 3: out += "March"; break;
case 4: out += "April"; break;
case 5: out += "May"; break;
case 6: out += "June"; break;
case 7: out += "July"; break;
case 8: out += "August"; break;
case 9: out += "September"; break;
case 10: out += "October"; break;
case 11: out += "November"; break;
case 12: out += "December"; break;
}
break;
case "M":
switch (month) {
case 1: out += "Jan"; break;
case 2: out += "Feb"; break;
case 3: out += "Mar"; break;
case 4: out += "Apr"; break;
case 5: out += "May"; break;
case 6: out += "Jun"; break;
case 7: out += "Jul"; break;
case 8: out += "Aug"; break;
case 9: out += "Sep"; break;
case 10: out += "Oct"; break;
case 11: out += "Nov"; break;
case 12: out += "Dec"; break;
}
break;
case "l":
switch (weekday) {
case 1: out += "Sunday"; break;
case 2: out += "Monday"; break;
case 3: out += "Tuesday"; break;
case 4: out += "Wednesday"; break;
case 5: out += "Thursday"; break;
case 6: out += "Friday"; break;
case 7: out += "Saturday"; break;
}
break;
case "D":
switch (weekday) {
case 1: out += "Sun"; break;
case 2: out += "Mon"; break;
case 3: out += "Tue"; break;
case 4: out += "Wed"; break;
case 5: out += "Thu"; break;
case 6: out += "Fri"; break;
case 7: out += "Sat"; break;
}
break;
case "S":
if (day >= 10 && day <= 20) out += "th";
else if ((day mod 10) == 1) out += "st";
else if ((day mod 10) == 2) out += "nd";
else if ((day mod 10) == 3) out += "rd";
else out += "th";
break;
case "Y": out += string(year); break;
case "y": out += string_copy(string(year),3,2); break;
case "m": if (month < 10) out += "0";
case "n": out += string(month); break;
case "d": if (day < 10) out += "0";
case "j": out += string(day); break;
case "H": if (hour24 < 10) out += "0";
case "G": out += string(hour24); break;
case "h": if (hour12 < 10) out += "0";
case "g": out += string(hour12); break;
case "i": if (minute < 10) out += "0"; out += string(minute); break;
case "s": if (second < 10) out += "0"; out += string(second); break;
case "a": if (hour24 < 12) out += "am" else out += "pm"; break;
case "A": if (hour24 < 12) out += "AM" else out += "PM"; break;
case "U": out += string(round(date_second_span(dat,25568.8333))); break;
case "z": out += string(date_get_day_of_year(dat)-1); break;
case "t": out += string(date_days_in_month(month)); break;
case "L": out += string(date_leap_year(dat)); break;
case "w": out += string(weekday-1); break;
case "N": out += string(((weekday+5) mod 7)+1); break;
case "W":
// 1+INT((A1-DATE(YEAR(A1+4-WEEKDAY(A1+6)),1,5)+WEEKDAY(DATE(YEAR(A1+4-WEEKDAY(A1+6)),1,3)))/7)
// 1 + INT(
// (
// A1
// - DATE(
// YEAR(A1+4-WEEKDAY(A1+6)),
// 1,
// 5
// )
// + WEEKDAY(
// DATE(
// YEAR(A1+4-WEEKDAY(A1+6)),
// 1,
// 3
// )
// )
// )
// / 7
// )
out += string(
1 + floor(
( // date_day_span(dat,date_create_date(date_get_year(date_inc_day(dat,4-date_get_weekday(date_inc_day(dat,6)))),1,5))
date_day_span(dat,
date_create_date(
date_get_year(date_inc_day(dat,4-date_get_weekday(date_inc_day(dat,6)))),
1,
5
)
)
+ date_get_weekday(
date_create_date(
date_get_year(date_inc_day(dat,4-date_get_weekday(date_inc_day(dat,6)))),
1,
3
)
)
)
/7
)
);
break;
default: out += c; break;
}
}
return out;
Source: E:\_xotgames\_prototypes\datetime-functions\date_format.gm6
xotmatrix commented
ISO 8601 year is also not working right.
case "o":
if (month == 1 && day <= 3 && week != 1) { out += string(year-1); break; }
if (month == 12 && day >= 29 && week == 1) { out += string(year+1); break; }