Hi everyone !
Something for HP PRIME:
Code:
//--------------------------------------
// Convert gregorian calendar dates
// YYYY.MMDD into yyyy-Www-d
// according to ISO 8601
// V0.1 (2015-W04-4)
//--------------------------------------
EXPORT ISOWeekDate(date)
BEGIN
LOCAL year,day,JDn;
LOCAL ISOWeekNb,ISOd,ISOYear;
// cut date YYYY.MMDD
year:=IP(date); // YYYY
day:=IP(FP(FP(date)*100)*100); // DD
ISOYear:=IP(date); // YYYY
// Find julian day number at noon
// from the gregorian date YYYY.MMDD
JDn:=DateG2JJ(date);
// Find day number according to ISO8601
// (Mo=1,Tue=2,...,Sun=7)
ISOd:=(JDn MOD 7)+1;
// Find week number according to ISO8601
// (1≤WeekNb≤53)
ISOWeekNb:=ISOWeekNum(JDn);
// Find year according to ISO8601
// - for 'normal' week: 2≤Week≤51
// - for 'pivotal' week:1,52,53
IF 1<ISOWeekNb<52 THEN
ISOYear:=IP(date);
ELSE
// possible week transitions between
// year N and N+1
//+---------+--+--+--+--+--+--+--+-+-------------
//|Monday |22|23|24|25|26|27|28|1|
//|Tuesday |23|24|25|26|27|28|29|2| THE
//|Wednesday|24|25|26|27|28|29|30|3|LAST WEEK OF
//|Thursday |25|26|27|28|29|30|31|4| YEAR N-1
//|Friday |26|27|28|29|30|31|01|5|
//|Saturday |27|28|29|30|31|01|02|6|(WEEK 52, 53)
//|Sunday |28|29|30|31|01|02|03|7|
//+---------+--+--+--+--+--+--+--+-+-------------
//|Monday |29|30|31|01|02|03|04|1|
//|Tuesday |30|31|01|02|03|04|05|2| THE
//|Wednesday|31|01|02|03|04|05|06|3|FIRST WEEK OF
//|Thursday |01|02|03|04|05|06|07|4| YEAR N
//|Friday |02|03|04|05|06|07|08|5|
//|Saturday |03|04|05|06|07|08|09|6| (WEEK 1)
//|Sunday |04|05|06|07|08|09|10|7|
//+---------+--+--+--+--+--+--+--+-+-------------
// ⇳
// Now lets translate this into
// some (many) lines of code
IF ISOWeekNb==1 THEN // first week ?
IF ISOd==1 THEN // Monday ?
IF 29≤day≤31 THEN
ISOYear:=IP(date)+1; // YYYY+1
ELSE
IF 1≤day≤4 THEN
ISOYear:=IP(date); // YYYY
END;
END;
END; // Monday
IF ISOd==2 THEN // Tuesday ?
IF 30≤day≤31 THEN
ISOYear:=IP(date)+1; // YYYY+1
ELSE
IF 1≤day≤5 THEN
ISOYear:=IP(date); // YYYY
END;
END;
END; // Tuesday
IF ISOd==3 THEN // Wednesday ?
IF day==31 THEN
ISOYear:=IP(date)+1; // YYYY+1
ELSE
IF 1≤day≤6 THEN
ISOYear:=IP(date); // YYYY
END;
END;
END; // Wednesday
IF ISOd==4 THEN // Thursday ?
IF 1≤day≤7 THEN
ISOYear:=IP(date); // YYYY
END;
END; // Thursday
IF ISOd==5 THEN // Friday ?
IF 2≤day≤8 THEN
ISOYear:=IP(date); // YYYY
END;
END; // Friday
IF ISOd==6 THEN // Saturday ?
IF 3≤day≤9 THEN
ISOYear:=IP(date); // YYYY
END;
END; // Saturday
IF ISOd==7 THEN // Sunday ?
IF 4≤day≤10 THEN
ISOYear:=IP(date); // YYYY
END;
END; // Sunday
ELSE // Week 1
IF 52≤ISOWeekNb≤53 THEN // last week ?
IF ISOd==1 THEN // Monday ?
IF 22≤day≤28 THEN
ISOYear:=IP(date); // YYYY
END;
END; // Monday
IF ISOd==2 THEN // Tuesday ?
IF 23≤day≤29 THEN
ISOYear:=IP(date); // YYYY
END;
END; // Tuesday
IF ISOd==3 THEN // Wednesday ?
IF 24≤day≤30 THEN
ISOYear:=IP(date); // YYYY
END;
END; // Wednesday
IF ISOd==4 THEN // Thursday ?
IF 25≤day≤31 THEN
ISOYear:=IP(date); // YYYY
END;
END;
IF ISOd==5 THEN // Friday ?
IF 26≤day≤31 THEN
ISOYear:=IP(date); // YYYY
ELSE
IF day==1 THEN
ISOYear:=IP(date)-1; // YYYY-1
END;
END;
END;
IF ISOd==6 THEN // Saturday ?
IF 27≤day≤31 THEN
ISOYear:=IP(date); // YYYY
ELSE
IF 1≤day≤2 THEN
ISOYear:=IP(date)-1; // YYYY-1
END;
END;
END;
IF ISOd==7 THEN // Sunday ?
IF 28≤day≤31 THEN
ISOYear:=IP(date); // YYYY
ELSE
IF 1≤day≤3 THEN
ISOYear:=IP(date)-1; // YYYY-1
END;
END;
END; // Sunday ?
END; // 52≤week≤53 ?
END; // week 1 ?
END; // 2≤week≤51 ?
// ( Phew ! Thanks CUT/COPY/PAST ! )
// TEXT Formatting
IF ISOWeekNb<10 THEN
RETURN ISOYear+"-W0"+ISOWeekNb+"-"+ISOd;
ELSE
RETURN ISOYear+"-W"+ISOWeekNb+"-"+ISOd;
END;
END; // Begin
//----------------------------------------------------
// Convert calendar (Gregorian) date
// to julian day number JDn at noon
// aaaa.mmjj => JDn
// e.g. 2000.0101 => 2451545 (J2000)
//----------------------------------------------------
DateG2JJ(date) // for date ≥ oct 15 1582 (2299161)
BEGIN
LOCAL year,month,day;
LOCAL cnt,diz;
// Cut the date YYYY.MMDD into sub parts
year:=IP(date); // YYYY
month:=IP(100*FP(date)); // MM
day:=IP(FP(FP(date)*100)*100); // DD
// Move the beginning of the year to
// March 1st (adding 1 day, e.g. feb 29th
// becomes easier if at the end)
IF month<3 THEN
year:=year-1;
month:=month+12;
END;
// Cut the year into parts
// (Needed for converting Gregorian
// calendar dates to JDN)
cnt:=IP(year/100); // [YY]YY
diz:=IP(year-100*IP(year/100)); //YY[YY]
// julian day number at noon
// from gregorian date YYYY.MMDD
RETURN IP((146097*cnt+6884480)/4)
+IP(1461*diz/4)
+IP((153*month-457)/5)
+day-1;
END;
//----------------------------------------------------
// Return the week number [1 - 52 sometimes 53]
// according to ISO 8601 from the julian day number
// (JDn≥2299161)
//----------------------------------------------------
ISOWeekNum(JD)
BEGIN
LOCAL d4;
d4:=(JD+31741-(JD MOD 7)) MOD 146097
MOD 36524 MOD 1461;
RETURN IP(((d4-IP(d4/1460)) MOD 365
+IP(d4/1460))/7+1);
END;
Convert calendar date YYYY.MMDD to ISO 8601 date yyyy-Www-d.
e.g. 2013.1231 => 2014-W01-2
Regards,
Damien