Post Reply 
A tiny New Year's programming challenge
01-22-2015, 11:24 PM (This post was last modified: 01-23-2015 10:32 AM by Damien.)
Post: #23
RE: A tiny New Year's programming challenge
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
Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
RE: A tiny New Year's programming challenge - Damien - 01-22-2015 11:24 PM



User(s) browsing this thread: 1 Guest(s)