Post Reply 
A tiny New Year's programming challenge
01-04-2015, 06:37 PM (This post was last modified: 01-04-2015 06:42 PM by Dieter.)
Post: #10
RE: A tiny New Year's programming challenge
(01-01-2015 04:51 PM)Dieter Wrote:  And here is your task: Write a program that accepts a valid Gregorian Date and returns the corresponding ISO week number, as well as the day number within that week.

Just before week 2 starts, here is what I got with my 34s. Dates may be entered in dd.mmyyyy or mm.ddyyyy format.

Code:
LBL "KW"  // "KW" is the common German abbreviation for "Kalenderwoche" ;-)
LocR 01   // a single temporary register (and one flag) will do
D->J
RCL L
YEAR
STO.00    // save year in R.00
SDR 004
INC X
SDR 002
INC X     // build 01.01yyyy
D->J      // JD(1 Jan)
#003
+         // JD(4 Jan), which is always in week 1
#007
IDIV
RCL*L     // = JD(4 Jan) - JD(4 Jan) mod 7 = day 1 of week 1
-         // # of days since day 1 of week 1
x>=0?     // date not before day 1 of week 1?
GTO 51
#007
+         // adjust negative day# by adding back 7 days
DEC.00    // week is last of previous year
RCL.00
XEQ 53    // get last week# of previous year
GTO 52    // and exit

LBL 51    // standard case
RCL X
#007
RMDR
x<> Y
#007
IDIV      // day# in Y, week# in X
RCL.00
XEQ 53    // get last week of year
x<? Y     // if computed week# is larger
INC.00    // increment year
x<? Y
CLx       // and set week# to first week in year
MIN

LBL 52    // exit routine
INC X     // adjust week# from 0...52 to 1...53
INC Y     // adjust day# from 0...6 to 1...7
RCL.00
SDR 004
+         // generate ww.yyyy
CLα
αIP.00    // build output string
α"-W"
#010
x>? Y
α"0"
DROP
αIP X
α"-"
αIP Y     // => "yyyy-Www-d"
TOP?      // if directly called by user,
VWα+X     // display formatted result
RTN       // in any case return ww.yyyy in X and day# in Y

LBL 53    // input: year
CF.01     // output: 51 or 52
LEAP?     // = last week# (0-based)
SF.01
SDR 004
INC X
SDR 002
INC X     // build 01.01yyyy
WDAY      // get weekday of 1 Jan
#004
-
x=0?      // is it Thursday?
SKIP 002  // then continue with x=0
FS?C.01   // if not and leap year:
INC X     // set result to 0 also for Wednesday (was 3-4=-1)
SIGN
ABS       // turn any non-zero value into 1
+/-
#052
+         // last week# = 52-0 resp. 52-1
RTN

R.00: year
Flag .01: set if leap year, clear otherwise


04.071979 XEQ"KW" => 1979-W27-3   27.1979  [x<>y]  3
01.012012 XEQ"KW" => 2011-W52-7   52.2011  [x<>y]  7
31.122004 XEQ"KW" => 2004-W53-5   53.2004  [x<>y]  5
31.122012 XEQ"KW" => 2013-W01-1    1.2013  [x<>y]  1

The subroutine at LBL 53 returns the last week# (zero-based) for a given year, i.e. 51 or 52. It checks whether the year starts with a Thursday or – if it is a leap year – with a Wednesday. These years have 53 weeks, otherwise 52.

Dieter
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 - Dieter - 01-04-2015 06:37 PM



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