string deBruijn = ""
for n=0 to 99 do
    string a = sprintf("%02d",n)
    integer a1 = a[1],
            a2 = a[2]
    if a2>=a1 then
        deBruijn &= iff(a1=a2?a1:a)
        for m=n+1 to 99 do
            string ms = sprintf("%02d",m)
            if ms[2]>a1 then
                deBruijn &= a&ms
            end if
        end for
   end if
end for
deBruijn &= "000"
printf(1,"de Bruijn sequence length: %d\n\n",length(deBruijn))
printf(1,"First 130 characters:\n%s\n\n",deBruijn[1..130])
printf(1,"Last 130 characters:\n%s\n\n",deBruijn[-130..-1])

function check(string text)
    sequence res = {}
    sequence found = repeat(0,10000)
    integer k
    for i=1 to length(text)-3 do
        k = to_integer(text[i..i+3],-1)+1
        if k!=0 then found[k] += 1 end if
    end for
    for i=1 to 10000 do
        k = found[i]
        if k!=1 then
            string e = sprintf("Pin number %04d ",i-1)
            e &= iff(k=0?"missing":sprintf("occurs %d times",k))
            res = append(res,e)
        end if
    end for
    k = length(res)
    if k=0 then
        res = "No errors found"
    else
        string s = iff(k=1?"":"s")
        res = sprintf("%d error%s found:\n ",{k,s})&join(res,"\n ")
    end if
    return res
end function

printf(1,"Missing 4 digit PINs in this sequence: %s\n", check(deBruijn))
printf(1,"Missing 4 digit PINs in the reversed sequence: %s\n",check(reverse(deBruijn)))
printf(1,"4444th digit in the sequence: %c (setting it to .)\n", deBruijn[4444])
deBruijn[4444] = '.'
printf(1,"Re-running checks: %s\n",check(deBruijn))


# from https://en.wikipedia.org/wiki/De_Bruijn_sequence

def de_bruijn(k, n):
    """
    de Bruijn sequence for alphabet k
    and subsequences of length n.
    """
    try:
        # let's see if k can be cast to an integer;
        # if so, make our alphabet a list
        _ = int(k)
        alphabet = list(map(str, range(k)))

    except (ValueError, TypeError):
        alphabet = k
        k = len(k)

    a = [0] * k * n
    sequence = []

    def db(t, p):
        if t > n:
            if n % p == 0:
                sequence.extend(a[1:p + 1])
        else:
            a[t] = a[t - p]
            db(t + 1, p)
            for j in range(a[t - p] + 1, k):
                a[t] = j
                db(t + 1, t)
    db(1, 1)
    return "".join(alphabet[i] for i in sequence)

def validate(db):
    """

    Check that all 10,000 combinations of 0-9 are present in
    De Bruijn string db.

    Validating the reversed deBruijn sequence:
      No errors found

    Validating the overlaid deBruijn sequence:
      4 errors found:
        PIN number 1459 missing
        PIN number 4591 missing
        PIN number 5814 missing
        PIN number 8145 missing

    """

    dbwithwrap = db+db[0:3]

    digits = '0123456789'

    errorstrings = []

    for d1 in digits:
        for d2 in digits:
            for d3 in digits:
                for d4 in digits:
                    teststring = d1+d2+d3+d4
                    if teststring not in dbwithwrap:
                        errorstrings.append(teststring)

    if len(errorstrings) > 0:
        print("  "+str(len(errorstrings))+" errors found:")
        for e in errorstrings:
            print("  PIN number "+e+"  missing")
    else:
        print("  No errors found")

db = de_bruijn(10, 4)

print(" ")
print("The length of the de Bruijn sequence is ", str(len(db)))
print(" ")
print("The first 130 digits of the de Bruijn sequence are: "+db[0:130])
print(" ")
print("The last 130 digits of the de Bruijn sequence are: "+db[-130:])
print(" ")
print("Validating the deBruijn sequence:")
validate(db)
dbreversed = db[::-1]
print(" ")
print("Validating the reversed deBruijn sequence:")
validate(dbreversed)
dboverlaid = db[0:4443]+'.'+db[4444:]
print(" ")
print("Validating the overlaid deBruijn sequence:")
validate(dboverlaid)


#lang racket

(define (de-bruijn k n)
  (define a (make-vector (* k n) 0))
  (define seq '())
  (define (db t p)
    (cond
      [(> t n) (when (= (modulo n p) 0)
                 (set! seq (cons (call-with-values
                                  (thunk (vector->values a 1 (add1 p)))
                                  list)
                                 seq)))]
      [else (vector-set! a t (vector-ref a (- t p)))
            (db (add1 t) p)
            (for ([j (in-range (add1 (vector-ref a (- t p))) k)])
              (vector-set! a t j)
              (db (add1 t) t))]))
  (db 1 1)
  (define seq* (append* (reverse seq)))
  (append seq* (take seq* (sub1 n))))

(define seq (de-bruijn 10 4))
(printf "The length of the de Bruijn sequence is ~a\n\n" (length seq))
(printf "The first 130 digits of the de Bruijn sequence are:\n~a\n\n"
        (take seq 130))
(printf "The last 130 digits of the de Bruijn sequence are:\n~a\n\n"
        (take-right seq 130))

(define (validate name seq)
  (printf "Validating the ~ade Bruijn sequence:\n" name)
  (define expected (for/set ([i (in-range 0 10000)]) i))
  (define actual (for/set ([a (in-list seq)]
                           [b (in-list (rest seq))]
                           [c (in-list (rest (rest seq)))]
                           [d (in-list (rest (rest (rest seq))))])
                   (+ (* 1000 a) (* 100 b) (* 10 c) d)))
  (define diff (set-subtract expected actual))
  (cond
    [(set-empty? diff) (printf "  No errors found\n")]
    [else (for ([n (in-set diff)])
            (printf "  ~a is missing\n" (~a n #:width 4 #:pad-string "0")))])
  (newline))

(validate "" seq)
(validate "reversed " (reverse seq))
(validate "overlaid " (list-update seq 4443 add1))


# Generate the sequence
my $seq;

for ^100 {
    my $a = .fmt: '%02d';
    next if $a.substr(1,1) < $a.substr(0,1);
    $seq ~= ($a.substr(0,1) == $a.substr(1,1)) ?? $a.substr(0,1) !! $a;
    for +$a ^..^ 100 {
        next if .fmt('%02d').substr(1,1) <= $a.substr(0,1);
        $seq ~= sprintf "%s%02d", $a, $_ ;
    }
}

$seq = $seq.comb.list.rotate((^10000).pick).join;

$seq ~= $seq.substr(0,3);

sub check ($seq) {
    my %chk;
    for ^($seq.chars) { %chk{$seq.substr( $_, 4 )}++ }
    put 'Missing: ', (^9999).grep( { not %chk{ .fmt: '%04d' } } ).fmt: '%04d';
    put 'Extra:   ', %chk.grep( *.value > 1 )».key.sort.fmt: '%04d';
}

## The Task
put "de Bruijn sequence length: " ~ $seq.chars;

put "\nFirst 130 characters:\n" ~ $seq.substr( 0, 130 );

put "\nLast 130 characters:\n" ~ $seq.substr( * - 130 );

put "\nIncorrect 4 digit PINs in this sequence:";
check $seq;

put "\nIncorrect 4 digit PINs in the reversed sequence:";
check $seq.flip;

my $digit = $seq.substr(4443,1);
put "\nReplacing the 4444th digit, ($digit) with { ($digit += 1) %= 10 }";
put "Incorrect 4 digit PINs in the revised sequence:";
$seq.substr-rw(4443,1) = $digit;
check $seq;


/*REXX pgm calculates the  de Bruijn  sequence for all pin numbers  (4 digit decimals). */
$=                                               /*initialize the  de Bruijn  sequence. */
#=10;   lastNode= (#-2)(#-2)(#-1)(#-2)           /*this number is formed when this # ···*/
                                                 /*  ··· is skipped near the cycle end. */
  do j=0  for 10;  $= $ || j;  jj= j || j        /*compose the left half of the numbers.*/
                                                 /* [↓]     "  right  "   "  "     "    */
                                do k=jj+1  to 99;      z= jj || right(k, 2, 0)
                                if z==lastNode  then iterate    /*the last node skipped.*/
                                if pos(z, $)\==0  then iterate  /*# in sequence? Skip it*/
                                $= $ || z        /* ◄─────────────────────────────────┐ */
                                end   /*k*/      /*append a number to the sequence──◄─┘ */

     do r= jj  to (j || 9);  b= right(r, 2, 0)   /*compose the left half of the numbers.*/
     if b==jj  then iterate
     $= $ || right(b, 2, 0)                      /* [↓]     "  right  "   "  "     "    */
                                do k= b+1  to 99;      z= right(b, 2, 0) || right(k, 2, 0)
                                if pos(z, $)\==0  then iterate  /*# in sequence? Skip it*/
                                $= $ || z        /* ◄─────────────────────────────────┐ */
                                end   /*k*/      /*append a number to the sequence──◄─┘ */
     end   /*r*/
  end      /*j*/
                      @deB= 'de Bruijn sequence' /*literal used in some SAY instructions*/
$= $ || left($, 3)        /*append 000*/         /*simulate "wrap-around" de Bruijn seq.*/
       say 'length of the' @deB " is " length($) /*display the length of  de Bruijn seq.*/
say;   say 'first 130 digits of the' @deB":"     /*display the title for the next line. */
       say left($, 130)                          /*display 130 left-most digits of seq. */
say;   say ' last 130 digits of the' @deB":"     /*display the title for the next line. */
       say right($, 130)                         /*display 130 right-most digits of seq.*/
say                                              /*display a blank line.                */
call val $                                       /*call the  VAL  sub for verification. */
               @deB= 'reversed'   @deB           /*next,  we'll check on a reversed seq.*/
$$= reverse($)                                   /*do what a mirror does,  reversify it.*/
call val $$                                      /*call the  VAL  sub for verification. */
$= overlay(., $, 4444)                           /*replace 4,444th digit with a period. */
               @deB= 'overlaid' subword(@deB, 2) /* [↑] this'll cause a validation barf.*/
call val $                                       /*call the  VAL  sub for verification. */
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
val: parse arg $$$;    e= 0;    _= copies('─',8) /*count of errors (missing PINs) so far*/
     say;      say _ 'validating the'    @deB"." /*display what's happening in the pgm. */
         do pin=0  for 1e4; pin4= right(pin,4,0) /* [↓]  maybe add leading zeros to pin.*/
         if pos(pin4, $$$)\==0  then iterate     /*Was number found?  Just as expected. */
         say 'PIN number '      pin       " wasn't found in"         @deb'.'
         e= e + 1                                /*bump the counter for number of errors*/
         end   /*pin*/                           /* [↑]  validate all 10,000 pin numbers*/
     if e==0  then e= 'No'                       /*Gooder English (sic) the error count.*/
     say _   e   'errors found.'                 /*display the number of errors found.  */
     return


def deBruijn(k, n)
    alphabet = "0123456789"
    @a = Array.new(k * n, 0)
    @seq = []

    def db(k, n, t, p)
        if t > n then
            if n % p == 0 then
                temp = @a[1 .. p]
                @seq.concat temp
            end
        else
            @a[t] = @a[t - p]
            db(k, n, t + 1, p)
            j = @a[t - p] + 1
            while j < k do
                @a[t] = j # & 0xFF
                db(k, n, t + 1, t)
                j = j + 1
            end
        end
    end
    db(k, n, 1, 1)

    buf = ""
    for i in @seq
        buf <<= alphabet[i]
    end
    return buf + buf[0 .. n-2]
end

def validate(db)
    le = db.length
    found = Array.new(10000, 0)
    errs = []
    # Check all strings of 4 consecutive digits within 'db'
    # to see if all 10,000 combinations occur without duplication.
    for i in 0 .. le-4
        s = db[i .. i+3]
        if s.scan(/\D/).empty? then
            found[s.to_i] += 1
        end
    end
    for i in 0 .. found.length - 1
        if found[i] == 0 then
            errs <<= ("    PIN number %04d missing" % [i])
        elsif found[i] > 1 then
            errs <<= ("    PIN number %04d occurs %d times" % [i, found[i]])
        end
    end
    if errs.length == 0 then
        print "  No errors found\n"
    else
        pl = (errs.length == 1) ? "" : "s"
        print "  ", errs.length, " error", pl, " found:\n"
        for err in errs
            print err, "\n"
        end
    end
end

db = deBruijn(10, 4)
print "The length of the de Bruijn sequence is ", db.length, "\n\n"
print "The first 130 digits of the de Bruijn sequence are: ", db[0 .. 129], "\n\n"
print "The last 130 digits of the de Bruijn sequence are: ", db[-130 .. db.length], "\n\n"

print "Validating the de Bruijn sequence:\n"
validate(db)
print "\n"

db[4443] = '.'
print "Validating the overlaid de Bruijn sequence:\n"
validate(db)


Imports System.Text

Module Module1

    ReadOnly DIGITS As String = "0123456789"

    Function DeBruijn(k As Integer, n As Integer) As String
        Dim alphabet = DIGITS.Substring(0, k)
        Dim a(k * n) As Byte
        Dim seq As New List(Of Byte)
        Dim db As Action(Of Integer, Integer) = Sub(t As Integer, p As Integer)
                                                    If t > n Then
                                                        If n Mod p = 0 Then
                                                            Dim seg = New ArraySegment(Of Byte)(a, 1, p)
                                                            seq.AddRange(seg)
                                                        End If
                                                    Else
                                                        a(t) = a(t - p)
                                                        db(t + 1, p)
                                                        Dim j = a(t - p) + 1
                                                        While j < k
                                                            a(t) = j
                                                            db(t + 1, t)
                                                            j += 1
                                                        End While
                                                    End If
                                                End Sub
        db(1, 1)
        Dim buf As New StringBuilder
        For Each i In seq
            buf.Append(alphabet(i))
        Next
        Dim b = buf.ToString
        Return b + b.Substring(0, n - 1)
    End Function

    Function AllDigits(s As String) As Boolean
        For Each c In s
            If c < "0" OrElse "9" < c Then
                Return False
            End If
        Next
        Return True
    End Function

    Sub Validate(db As String)
        Dim le = db.Length
        Dim found(10000) As Integer
        Dim errs As New List(Of String)
        ' Check all strings of 4 consecutive digits within 'db'
        ' to see if all 10,000 combinations occur without duplication.
        For i = 1 To le - 3
            Dim s = db.Substring(i - 1, 4)
            If (AllDigits(s)) Then
                Dim n As Integer = Nothing
                Integer.TryParse(s, n)
                found(n) += 1
            End If
        Next
        For i = 1 To 10000
            If found(i - 1) = 0 Then
                errs.Add(String.Format("    PIN number {0,4} missing", i - 1))
            ElseIf found(i - 1) > 1 Then
                errs.Add(String.Format("    PIN number {0,4} occurs {1} times", i - 1, found(i - 1)))
            End If
        Next
        Dim lerr = errs.Count
        If lerr = 0 Then
            Console.WriteLine("  No errors found")
        Else
            Dim pl = If(lerr = 1, "", "s")
            Console.WriteLine("  {0} error{1} found:", lerr, pl)
            errs.ForEach(Sub(x) Console.WriteLine(x))
        End If
    End Sub

    Function Reverse(s As String) As String
        Dim arr = s.ToCharArray
        Array.Reverse(arr)
        Return New String(arr)
    End Function

    Sub Main()
        Dim db = DeBruijn(10, 4)
        Dim le = db.Length

        Console.WriteLine("The length of the de Bruijn sequence is {0}", le)
        Console.WriteLine(vbNewLine + "The first 130 digits of the de Bruijn sequence are: {0}", db.Substring(0, 130))
        Console.WriteLine(vbNewLine + "The last 130 digits of the de Bruijn sequence are: {0}", db.Substring(le - 130, 130))

        Console.WriteLine(vbNewLine + "Validating the deBruijn sequence:")
        Validate(db)

        Console.WriteLine(vbNewLine + "Validating the reversed deBruijn sequence:")
        Validate(Reverse(db))

        Dim bytes = db.ToCharArray
        bytes(4443) = "."
        db = New String(bytes)
        Console.WriteLine(vbNewLine + "Validating the overlaid deBruijn sequence:")
        Validate(db)
    End Sub

End Module


import "/fmt" for Fmt
import "/str" for Str

var deBruijn = ""
for (n in 0..99) {
    var a = Fmt.rjust(2, n, "0")
    var a1 = a[0].bytes[0]
    var a2 = a[1].bytes[0]
    if (a2 >= a1) {
        deBruijn = deBruijn + ((a1 == a2) ? String.fromByte(a1): a)
        var m = n + 1
        while (m <= 99) {
            var ms = Fmt.rjust(2, m, "0")
            if (ms[1].bytes[0] > a1) deBruijn = deBruijn + a + ms
            m = m + 1
        }
    }
}

deBruijn = deBruijn + "000"
System.print("de Bruijn sequence length: %(deBruijn.count)\n")
System.print("First 130 characters:\n%(deBruijn[0...130])\n")
System.print("Last 130 characters:\n%(deBruijn[-130..-1])\n")

var check = Fn.new { |text|
    var res = []
    var found = List.filled(10000, 0)
    var k = 0
    for (i in 0...(text.count-3)) {
        var s = text[i..i+3]
        if (Str.allDigits(s)) {
            k = Num.fromString(s)
            found[k] = found[k] + 1
        }
    }
    for (i in 0...10000) {
        k = found[i]
        if (k != 1) {
            var e = "  Pin number %(Fmt.dz(4, i)) "
            e = e + ((k == 0) ? "missing" : "occurs %(k) times")
            res.add(e)
        }
    }
    k = res.count
    if (k == 0) {
        res = "No errors found"
    } else {
        var s = (k == 1) ? "" : "s"
        res = "%(k) error%(s) found:\n" + res.join("\n")
    }
    return res
}

System.print("Missing 4 digit PINs in this sequence: %(check.call(deBruijn))")
System.print("Missing 4 digit PINs in the reversed sequence: %(check.call(deBruijn[-1..0]))")

System.print("\n4,444th digit in the sequence: '%(deBruijn[4443])' (setting it to '.')")
deBruijn = deBruijn[0..4442] + "." + deBruijn[4444..-1]
System.print("Re-running checks: %(check.call(deBruijn))")


dbSeq:=Data();	// a byte/character buffer
foreach n in (100){
   a,a01,a11 := "%02d".fmt(n), a[0,1], a[1,1];
   if(a11<a01) continue;
   dbSeq.append( if(a01==a11) a01 else a );
   foreach m in ([n+1 .. 99]){
      if("%02d".fmt(m)[1,1] <= a01) continue;
      dbSeq.append("%s%02d".fmt(a,m));
   }
}
dbSeq.append("000");


V format_str = ‘%B %d %Y %I:%M%p’
print((time:strptime(‘March 7 2009 7:30pm’, format_str)
     + TimeDelta(hours' 12)).strftime(format_str))


with Ada.Calendar;
with Ada.Calendar.Formatting;
with Ada.Calendar.Time_Zones;
with Ada.Integer_Text_IO;
with Ada.Text_IO;

procedure Date_Manipulation is

   type Month_Name_T is
     (January, February, March, April, May, June,
      July, August, September, October, November, December);

   type Time_Zone_Name_T is (EST, Lisbon);

   type Period_T is (AM, PM);

   package TZ renames Ada.Calendar.Time_Zones;
   use type TZ.Time_Offset;

   Time_Zone_Offset : array (Time_Zone_Name_T) of TZ.Time_Offset :=
     (EST => -5 * 60,
      Lisbon => 0);

   Period_Offset : array (Period_T) of Natural :=
     (AM => 0,
      PM => 12);

   package Month_Name_IO is
      new Ada.Text_IO.Enumeration_IO (Month_Name_T);

   package Time_Zone_Name_IO is
      new Ada.Text_IO.Enumeration_IO (Time_Zone_Name_T);

   package Period_IO is
      new Ada.Text_IO.Enumeration_IO (Period_T);

   package Std renames Ada.Calendar;
   use type Std.Time;

   package Fmt renames Std.Formatting;

   function To_Number (Name : Month_Name_T) return Std.Month_Number is
   begin
      return Std.Month_Number (Month_Name_T'Pos (Name) + 1);
   end;

   function To_Time (S : String) return Std.Time is
      Month : Month_Name_T;
      Day : Std.Day_Number;
      Year : Std.Year_Number;
      Hour : Fmt.Hour_Number;
      Minute : Fmt.Minute_Number;
      Period : Period_T;
      Time_Zone : Time_Zone_Name_T;
      I : Natural;
   begin
      Month_Name_IO.Get
        (From => S, Item => Month, Last => I);
      Ada.Integer_Text_IO.Get
        (From => S (I + 1 .. S'Last), Item => Day, Last => I);
      Ada.Integer_Text_IO.Get
        (From => S (I + 1 .. S'Last), Item => Year, Last => I);
      Ada.Integer_Text_IO.Get
        (From => S (I + 1 .. S'Last), Item => Hour, Last => I);
      Ada.Integer_Text_IO.Get
        (From => S (I + 2 .. S'Last), Item => Minute, Last => I);
         --  here we start 2 chars down to skip the ':'
      Period_IO.Get
        (From => S (I + 1 .. S'Last), Item => Period, Last => I);
      Time_Zone_Name_IO.Get
        (From => S (I + 1 .. S'Last), Item => Time_Zone, Last => I);
      return Fmt.Time_Of
        (Year => Year,
         Month => To_Number (Month),
         Day => Day,
         Hour => Hour + Period_Offset (Period),
         Minute => Minute,
         Second => 0,
         Time_Zone => Time_Zone_Offset (Time_Zone));
   end;

   function Img
     (Date : Std.Time; Zone : Time_Zone_Name_T) return String is
   begin
      return
         Fmt.Image (Date => Date, Time_Zone => Time_Zone_Offset (Zone)) &
         " " & Time_Zone_Name_T'Image (Zone);
   end;

   T1, T2 : Std.Time;
   use Ada.Text_IO;
begin
   T1 := To_Time ("March 7 2009 7:30pm EST");
   T2 := T1 + 12.0 * 60.0 * 60.0;
   Put_Line ("T1 => " & Img (T1, EST) & " = " & Img (T1, Lisbon));
   Put_Line ("T2 => " & Img (T2, EST) & " = " & Img (T2, Lisbon));
end;


set x to "March 7 2009 7:30pm EST"
return (date x) + 12 * hours


; a tiny helper, so that we aren't too repetitive
formatDate: function [dt][
    to :string .format: "MMMM d yyyy h:mmtt" dt
]

initial: "March 7 2009 7:30pm EST"

; chop timezone off
initial: join.with:" " chop split.words initial
initial: to :date .format: "MMMM d yyyy h:mmtt" initial

print ["initial:"           formatDate initial]
print ["after 12 hours:"    formatDate after.hours:12 initial]


DateString := "March 7 2009 7:30pm EST"

; split the given string with RegExMatch
Needle := "^(?P<mm>\S*) (?P<d>\S*) (?P<y>\S*) (?P<t>\S*) (?P<tz>\S*)$"
RegExMatch(DateString, Needle, $)

; split the time with RegExMatch
Needle := "^(?P<h>\d+):(?P<min>\d+)(?P<xm>[amp]+)$"
RegExMatch($t, Needle, $)

; convert am/pm to 24h format
$h += ($xm = "am") ? 0 : 12

; knitting YYYYMMDDHH24MI format
_YYYY := $y
_MM   := Get_MonthNr($mm)
_DD   := SubStr("00" $d, -1) ; last 2 chars
_HH24 := SubStr("00" $h, -1) ; last 2 chars
_MI   := $min
YYYYMMDDHH24MI := _YYYY _MM _DD _HH24 _MI

; add 12 hours as requested
EnvAdd, YYYYMMDDHH24MI, 12, Hours
FormatTime, HumanReadable, %YYYYMMDDHH24MI%, d/MMM/yyyy  HH:mm

; add 5 hours to convert to different timezone (GMT)
EnvAdd, YYYYMMDDHH24MI, 5, Hours
FormatTime, HumanReadable_GMT, %YYYYMMDDHH24MI%, d/MMM/yyyy  HH:mm

; output
MsgBox, % "Given: " DateString "`n`n"
        . "12 hours later:`n"
        . "(" $tz "):`t" HumanReadable "h`n"
        . "(GMT):`t" HumanReadable_GMT "h`n"

;---------------------------------------------------------------------------
Get_MonthNr(Month) { ; convert named month to 2-digit number
;---------------------------------------------------------------------------
    If (Month = "January")
        Result := "01"
    Else If (Month = "February")
        Result := "02"
    Else If (Month = "March")
        Result := "03"
    Else If (Month = "April")
        Result := "04"
    Else If (Month = "May")
        Result := "05"
    Else If (Month = "June")
        Result := "06"
    Else If (Month = "July")
        Result := "07"
    Else If (Month = "August")
        Result := "08"
    Else If (Month = "September")
        Result := "09"
    Else If (Month = "October")
        Result := "10"
    Else If (Month = "November")
        Result := "11"
    Else If (Month = "December")
        Result := "12"
    Return, Result
}


# syntax: GAWK -f DATE_MANIPULATION.AWK
BEGIN {
    fmt = "%a %Y-%m-%d %H:%M:%S %Z" # DAY YYYY-MM-DD HH:MM:SS TZ
    split("March 7 2009 7:30pm EST",arr," ")
    M = (index("JanFebMarAprMayJunJulAugSepOctNovDec",substr(arr[1],1,3)) + 2) / 3
    D = arr[2]
    Y = arr[3]
    hhmm = arr[4]
    hh = substr(hhmm,1,index(hhmm,":")-1) + 0
    mm = substr(hhmm,index(hhmm,":")+1,2) + 0
    if (hh == 12 && hhmm ~ /am/) { hh = 0 }
    else if (hh < 12 && hhmm ~ /pm/) { hh += 12 }
    time = mktime(sprintf("%d %d %d %d %d %d",Y,M,D,hh,mm,0))
    printf("time:    %s\n",strftime(fmt,time))
    time += 12*60*60
    printf("+12 hrs: %s\n",strftime(fmt,time))
    exit(0)
}


@echo off

call:Date_Manipulation "March 7 2009 7:30pm EST"
call:Date_Manipulation "February 28 2009 2:28pm EST"
call:Date_Manipulation "February 29 2000 9:52pm EST"
pause>nul
exit /b

:Date_Manipulation
setlocal enabledelayedexpansion

:: These are the arrays we'll be using
set daysinmonth=31 28 31 30 31 30 31 31 30 31 30 31
set namesofmonths=January February March April May June July August September October November December

:: Separate the date given ("%1") into respective variables. Note: For now the "am/pm" is attached to %minutes%
for /f "tokens=1,2,3,4,5,6 delims=: " %%i in ("%~1") do (
  set monthname=%%i
  set day=%%j
  set year=%%k
  set hour=%%l
  set minutes=%%m
  set timezone=%%n
)

:: Separate the am/pm and the minutes value into different variables
set ampm=%minutes:~2,2%
set minutes=%minutes:~0,2%

:: Check if the day needs to be changed based on the status of "am/pm"
if %ampm%==pm (
  set /a day+=1
  set ampm=am
) else (
  set ampm=pm
)

:: Get the number corresponding to the month given
set tempcount=0
for %%i in (%namesofmonths%) do (
  set /a tempcount+=1
  if %monthname%==%%i set monthcount=!tempcount!
)

:: As this step may may be needed to repeat if the month needs to be changed, we add a label here
:getdaysinthemonth
:: Work out how many days are in the current month
set tempcount=0
for %%i in (%daysinmonth%) do (
  set /a tempcount+=1
  if %monthcount%==!tempcount! set daysinthemonth=%%i
)

:: If the month is February, check if it is a leap year. If so, add 1 to the amount of days in the month
if %daysinthemonth%==28 (
  set /a leapyearcheck=%year% %% 4
  if !leapyearcheck!==0 set /a daysinthemonth+=1
)

:: Check if the month needs to be changed based on the current day and how many days there are in the current month
if %day% gtr %daysinthemonth% (
  set /a monthcount+=1
  set day=1
  if !monthcount! gtr 12 (
    set monthcount=1
    set /a year+=1
  )
  goto getdaysinthemonth
)
:: Everything from :getdaysinthemonth will be repeated once if the month needs to be changed

:: This block is only required to change the name of the month for the output, however as you have %monthcount%, this is optional
set tempcount=0
for %%i in (%namesofmonths%) do (
  set /a tempcount+=1
  if %monthcount%==!tempcount! set monthname=%%i
)

echo Original    - %~1
echo Manipulated - %monthname% %day% %year% %hour%:%minutes%%ampm% %timezone%
exit /b


      INSTALL @lib$+"DATELIB"

      date$ = "March 7 2009 7:30pm EST"

      mjd% = FN_readdate(date$, "mdy", 0)
      colon% = INSTR(date$, ":")
      hours% = VAL(MID$(date$, colon%-2))
      IF INSTR(date$, "am") IF hours%=12  hours% -= 12
      IF INSTR(date$, "pm") IF hours%<>12 hours% += 12
      mins% = VAL(MID$(date$, colon%+1))

      now% = mjd% * 1440 + hours% * 60 + mins%
      new% = now% + 12 * 60 : REM 12 hours later

      PRINT FNformat(new%, "EST")
      PRINT FNformat(new% + 5 * 60, "GMT")
      PRINT FNformat(new% - 3 * 60, "PST")
      END

      DEF FNformat(datetime%, zone$)
      LOCAL mjd%, hours%, mins%, ampm$
      mjd% = datetime% DIV 1440
      hours% = (datetime% DIV 60) MOD 24
      mins% = datetime% MOD 60

      IF hours% < 12 THEN ampm$ = "am" ELSE ampm$ = "pm"
      IF hours% = 0 hours% += 12
      IF hours% > 12 hours% -= 12

      = FN_date$(mjd%, "MMMM d yyyy") + " " + STR$(hours%) + \
      \ ":" + RIGHT$("0"+STR$(mins%), 2) + ampm$ + " " + zone$
      ENDPROC


#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
  struct tm ts;
  time_t t;
  const char *d = "March 7 2009 7:30pm EST";

  strptime(d, "%B %d %Y %I:%M%p %Z", &ts);
  /* ts.tm_hour += 12; instead of t += 12*60*60
     works too. */
  t = mktime(&ts);
  t += 12*60*60;
  printf("%s", ctime(&t));

  return EXIT_SUCCESS;
}


class Program
{
    static void Main(string[] args)
    {
        CultureInfo ci=CultureInfo.CreateSpecificCulture("en-US");
        string dateString = "March 7 2009 7:30pm EST";
        string format = "MMMM d yyyy h:mmtt z";
        DateTime myDateTime = DateTime.ParseExact(dateString.Replace("EST","+6"),format,ci) ;
        DateTime newDateTime = myDateTime.AddHours(12).AddDays(1) ;
        Console.WriteLine(newDateTime.ToString(format).Replace("-5","EST")); //probably not the best way to do this

        Console.ReadLine();
    }
}


#include <string>
#include <iostream>
#include <boost/date_time/local_time/local_time.hpp>
#include <sstream>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <vector>
#include <boost/algorithm/string.hpp>
#include <cstdlib>
#include <locale>

int main( ) {
   std::string datestring ("March 7 2009 7:30pm EST" ) ;
   //we must first parse the date string into a date , a time and a time
   //zone part , to take account of present restrictions in the input facets
   //of the Boost::DateTime library used for this example
   std::vector<std::string> elements ;
   //parsing the date string
   boost::split( elements , datestring , boost::is_any_of( " " ) ) ;
   std::string datepart = elements[ 0 ] + " " + "0" + elements[ 1 ] + " " +
      elements[ 2 ] ; //we must add 0 to avoid trouble with the boost::date_input format strings
   std::string timepart = elements[ 3 ] ;
   std::string timezone = elements[ 4 ] ;
   const char meridians[ ] = { 'a' , 'p' } ;
   //we have to find out if the time is am or pm, to change the hours appropriately
   std::string::size_type found = timepart.find_first_of( meridians, 0 ) ;
   std::string twelve_hour ( timepart.substr( found , 1 ) ) ;
   timepart = timepart.substr( 0 , found ) ; //we chop off am or pm
   elements.clear( ) ;
   boost::split( elements , timepart , boost::is_any_of ( ":" ) ) ;
   long hour = std::atol( (elements.begin( ))->c_str( ) ) ;// hours in the string
   if ( twelve_hour == "p" ) //it's post meridian, we're converting to 24-hour-clock
      hour += 12 ;
   long minute = std::atol( ( elements.begin( ) + 1)->c_str( ) ) ;
   boost::local_time::tz_database tz_db ;
   tz_db.load_from_file( "/home/ulrich/internetpages/date_time_zonespec.csv" ) ;
   //according to the time zone database, this corresponds to one possible EST time zone
   boost::local_time::time_zone_ptr dyc = tz_db.time_zone_from_region( "America/New_York" ) ;
   //this is the string input format to initialize the date field
   boost::gregorian::date_input_facet *f =
      new boost::gregorian::date_input_facet( "%B %d %Y"  ) ;
   std::stringstream ss ;
   ss << datepart ;
   ss.imbue( std::locale( std::locale::classic( ) , f ) ) ;
   boost::gregorian::date d ;
   ss >> d ;
   boost::posix_time::time_duration td (  hour , minute , 0  ) ;
   //that's how we initialize the New York local time , by using date and adding
   //time duration with values coming from parsed date input string
   boost::local_time::local_date_time lt ( d , td ,  dyc ,
	 boost::local_time::local_date_time::NOT_DATE_TIME_ON_ERROR ) ;
   std::cout << "local time: " << lt << '\n' ;
   ss.str( "" ) ;
   ss << lt ;
   //we have to add 12 hours, so a new time duration object is created
   boost::posix_time::time_duration td2 (12 , 0 , 0 , 0 ) ;
   boost::local_time::local_date_time ltlater = lt + td2 ; //local time 12 hours later
   boost::gregorian::date_facet *f2 =
      new boost::gregorian::date_facet( "%B %d %Y , %R %Z" ) ;
   std::cout.imbue( std::locale( std::locale::classic( ) , f2 ) ) ;
   std::cout << "12 hours after " << ss.str( )  << " it is " << ltlater << " !\n" ;
   //what's New York time in the Berlin time zone ?
   boost::local_time::time_zone_ptr bt = tz_db.time_zone_from_region( "Europe/Berlin" ) ;
   std::cout.imbue( std::locale( "de_DE.UTF-8" ) ) ; //choose the output forman appropriate for the time zone
   std::cout << "This corresponds to " << ltlater.local_time_in( bt ) << " in Berlin!\n" ;
   return 0 ;
}


(import java.util.Date
	java.text.SimpleDateFormat)

(defn time+12 [s]
  (let [sdf (SimpleDateFormat. "MMMM d yyyy h:mma zzz")]
    (-> (.parse sdf s)
	(.getTime ,)
	(+ , 43200000)
	long
	(Date. ,)
	(->> , (.format sdf ,)))))


       identification division.
       program-id. date-manipulation.

       environment division.
       configuration section.
       repository.
           function all intrinsic.

       data division.
       working-storage section.
       01 given-date.
          05 filler            value z"March 7 2009 7:30pm EST".
       01 date-spec.
          05 filler            value z"%B %d %Y %I:%M%p %Z".

       01 time-struct.
          05 tm-sec            usage binary-long.
          05 tm-min            usage binary-long.
          05 tm-hour           usage binary-long.
          05 tm-mday           usage binary-long.
          05 tm-mon            usage binary-long.
          05 tm-year           usage binary-long.
          05 tm-wday           usage binary-long.
          05 tm-yday           usage binary-long.
          05 tm-isdst          usage binary-long.
          05 tm-gmtoff         usage binary-c-long.
          05 tm-zone           usage pointer.
       01 scan-index           usage pointer.

       01 time-t               usage binary-c-long.
       01 time-tm              usage pointer.

       01 reform-buffer        pic x(64).
       01 reform-length        usage binary-long.

       01 current-locale       usage pointer.

       01 iso-spec             constant as "YYYY-MM-DDThh:mm:ss+hh:mm".
       01 iso-date             constant as "2009-03-07T19:30:00-05:00".
       01 date-integer         pic 9(9).
       01 time-integer         pic 9(9).

       procedure division.

       call "strptime" using
           by reference given-date
           by reference date-spec
           by reference time-struct
           returning scan-index
           on exception
               display "error calling strptime" upon syserr
       end-call
       display "Given: " given-date

       if scan-index not equal null then
           *> add 12 hours, and reform as local
           call "mktime" using time-struct returning time-t
           add 43200 to time-t
           perform form-datetime

           *> reformat as Pacific time
           set environment "TZ" to "PST8PDT"
           call "tzset" returning omitted
           perform form-datetime

           *> reformat as Greenwich mean
           set environment "TZ" to "GMT"
           call "tzset" returning omitted
           perform form-datetime

           *> reformat for Tokyo time, as seen in Hong Kong
           set environment "TZ" to "Japan"
           call "tzset" returning omitted
           call "setlocale" using by value 6 by content z"en_HK.utf8"
               returning current-locale
               on exception
                   display "error with setlocale" upon syserr
           end-call
           move z"%c" to date-spec
           perform form-datetime
       else
           display "date parse error" upon syserr
       end-if

      *> A more standard COBOL approach, based on ISO8601
       display "Given: " iso-date
       move integer-of-formatted-date(iso-spec, iso-date)
         to date-integer

       move seconds-from-formatted-time(iso-spec, iso-date)
         to time-integer

       add 43200 to time-integer
       if time-integer greater than 86400 then
           subtract 86400 from time-integer
           add 1 to date-integer
       end-if
       display "       " substitute(formatted-datetime(iso-spec
                   date-integer, time-integer, -300), "T", "/")

       goback.

       form-datetime.
       call "localtime" using time-t returning time-tm
       call "strftime" using
           by reference reform-buffer
           by value length(reform-buffer)
           by reference date-spec
           by value time-tm
           returning reform-length
           on exception
               display "error calling strftime" upon syserr
       end-call
       if reform-length > 0 and <= length(reform-buffer) then
           display "       " reform-buffer(1 : reform-length)
       else
           display "date format error" upon syserr
       end-if
       .
       end program date-manipulation.


time = Time.parse("March 7 2009 7:30pm EST", "%B %-d %Y %l:%M%p", Time::Location.load("EST"))

time += 12.hours
puts time                                          # 2009-03-08 07:30:00 -05:00
puts time.in(Time::Location.load("Europe/Berlin")) # 2009-03-08 13:30:00 +01:00


import std.stdio;
import std.format;
import std.datetime;
import std.algorithm;

enum months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];

void main()
{
  // input
  string date = "March 7 2009 7:30pm EST";

  // parsing date string to integer values
  string month, md, tz;
  int day, year, hour, minute;
  date.formattedRead("%s %d %d %d:%d%s %s", &month, &day, &year, &hour, &minute, &md, &tz);
  int mon = cast (int) months.countUntil(month) + 1;

  // convert to 24-hour
  if (md == "pm")
    hour += 12;

  // create date from integer
  DateTime dt = DateTime(year, mon, day, hour, minute);

  // output
  writeln(dt);
  writeln(dt + 12.hours);

}


program DateManipulation;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  DateUtils;

function MonthNumber(aMonth: string): Word;
begin
  //Convert a string value representing the month
  //to its corresponding numerical value
  if aMonth = 'January' then Result:= 1
  else if aMonth = 'February' then Result:= 2
  else if aMonth = 'March' then Result:= 3
  else if aMonth = 'April' then Result:= 4
  else if aMonth = 'May' then Result:= 5
  else if aMonth = 'June' then Result:= 6
  else if aMonth = 'July' then Result:= 7
  else if aMonth = 'August' then Result:= 8
  else if aMonth = 'September' then Result:= 9
  else if aMonth = 'October' then Result:= 10
  else if aMonth = 'November' then Result:= 11
  else if aMonth = 'December' then Result:= 12
  else Result:= 12;
end;

function ParseString(aDateTime: string): TDateTime;
var
  strDay,
  strMonth,
  strYear,
  strTime: string;
  iDay,
  iMonth,
  iYear: Word;
  TimePortion: TDateTime;
begin
  //Decode the month from the given string
  strMonth:= Copy(aDateTime, 1, Pos(' ', aDateTime) - 1);
  Delete(aDateTime, 1, Pos(' ', aDateTime));
  iMonth:= MonthNumber(strMonth);

  //Decode the day from the given string
  strDay:= Copy(aDateTime, 1, Pos(' ', aDateTime) - 1);
  Delete(aDateTime, 1, Pos(' ', aDateTime));
  iDay:= StrToIntDef(strDay, 30);

  //Decode the year from the given string
  strYear:= Copy(aDateTime, 1, Pos(' ', aDateTime) -1);
  Delete(aDateTime, 1, Pos(' ', aDateTime));
  iYear:= StrToIntDef(strYear, 1899);

  //Decode the time value from the given string
  strTime:= Copy(aDateTime, 1, Pos(' ', aDateTime) -1);

  //Encode the date value and assign it to result
  Result:= EncodeDate(iYear, iMonth, iDay);

  //Encode the time value and add it to result
  if TryStrToTime(strTime, TimePortion) then
    Result:= Result + TimePortion;
end;

function Add12Hours(aDateTime: string): string;
var
  tmpDateTime: TDateTime;
begin
  //Adding 12 hours to the given
  //date time string value
  tmpDateTime:= ParseString(aDateTime);
  tmpDateTime:= IncHour(tmpDateTime, 12);

  //Formatting the output
  Result:= FormatDateTime('mm/dd/yyyy hh:mm AM/PM', tmpDateTime);
end;

begin
  Writeln(Add12Hours('March 7 2009 7:30pm EST'));
  Readln;
end.


(define my-date (string->date "March 7 2009 7:30 pm EST"))
    → Sun Mar 08 2009 01:30:00 GMT+0100 (CET)

(date-add! my-date (* 12 3600))
    → Sun Mar 08 2009 13:30:00 GMT+0100 (CET)
(string->date my-date)

(date->string my-date)
    → "8/3/2009 13:30:00" ;; human localized, Paris time.


-module( date_manipulation ).

-export( [task/0] ).

task() ->
	{Date_time, TZ} = date_time_tz_from_string( "March 7 2009 7:30pm EST" ),
	Seconds1 = calendar:datetime_to_gregorian_seconds( Date_time ),
	Seconds2 = calendar:datetime_to_gregorian_seconds( {calendar:gregorian_days_to_date(0), {12, 0, 0}} ),
	Date_time_later = calendar:gregorian_seconds_to_datetime( Seconds1 + Seconds2 ),
	{Date_time_later, TZ}.

date_time_tz_from_string( String ) ->
	[Month, Date, Year, Time, TZ] = string:tokens( String, " " ),
	[Hour, Minute] = string:tokens( Time, ":" ),
	{{date_from_strings(Year, Month, Date), time_from_strings(Hour, Minute)}, TZ}.

date_from_strings( Year, Month, Date ) ->
	{erlang:list_to_integer(Year), date_from_strings_month(Month), erlang:list_to_integer(Date)}.

date_from_strings_month( "January" ) -> 1;
date_from_strings_month( "February" ) -> 2;
date_from_strings_month( "March" ) -> 3;
date_from_strings_month( "April" ) -> 4;
date_from_strings_month( "May" ) -> 5;
date_from_strings_month( "June" ) -> 6;
date_from_strings_month( "July" ) -> 7;
date_from_strings_month( "August" ) -> 8;
date_from_strings_month( "September" ) -> 9;
date_from_strings_month( "October" ) -> 10;
date_from_strings_month( "November" ) -> 11;
date_from_strings_month( "December" ) -> 12.

time_from_strings( Hour, Minute_12hours ) ->
	{ok, [Minute], AM_PM} = io_lib:fread("~d", Minute_12hours ),
	{time_from_strings_hour( Hour, string:to_lower(AM_PM) ), Minute, 0}.

time_from_strings_hour( Hour, "am" ) -> erlang:list_to_integer( Hour );
time_from_strings_hour( Hour, "pm" ) -> erlang:list_to_integer( Hour ) + 12.


--Date Manipulation task from Rosetta Code wiki
--User:Lnettnay

include std/datetime.e

datetime dt

dt = new(2009, 3, 7, 19, 30)
dt = add(dt, 12, HOURS)
printf(1, "%s EST\n", {format(dt, "%B %d %Y %I:%M %p")})


open System

let main() =
  let est = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time")
  let date = DateTime.Parse("March 7 2009 7:30pm -5" )
  let date_est = TimeZoneInfo.ConvertTime( date, est)
  let date2 = date.AddHours(12.0)
  let date2_est = TimeZoneInfo.ConvertTime( date2, est)
  Console.WriteLine( "Original date in local time : {0}", date )
  Console.WriteLine( "Original date in EST        : {0}", date_est )
  Console.WriteLine( "12 hours later in local time: {0}", date2 )
  Console.WriteLine( "12 hours later in EST       : {0}", date2_est )

main()


USING: calendar calendar.english calendar.format calendar.parser
combinators io kernel math math.parser sequences splitting
unicode ;
IN: rosetta-code.date-manipulation

! e.g. "7:30pm" -> 19 30
: parse-hm ( str -- hours minutes )
    ":" split first2 [ digit? ] partition
    [ [ string>number ] [email protected] ] dip "pm" = [ [ 12 + ] dip ] when ;

! Parse a date in the format "March 7 2009 7:30pm EST"
: parse-date ( str -- timestamp )
    " " split {
        [ first month-names index 1 + ]
        [ second string>number ]
        [ third string>number -rot ]
        [ fourth parse-hm 0 ]
        [ last parse-rfc822-gmt-offset ]
    } cleave <timestamp> ;

"March 7 2009 7:30pm EST" parse-date dup 12 hours time+
[ timestamp>rfc822 print ] [email protected]


fansh> d := DateTime.fromLocale("March 7 2009 7:30pm EST", "MMMM D YYYY h:mmaa zzz")
fansh> d
2009-03-07T19:30:00-05:00 EST
fansh> d + 12hr
2009-03-08T07:30:00-05:00 EST
fansh> (d+12hr).toTimeZone(TimeZone("London")) // the extra credit!
2009-03-08T12:30:00Z London


' FB 1.05.0 Win64

#include "vbcompat.bi"

Sub split (s As String, sepList As String, result() As String, removeEmpty As Boolean = False)
  If s = "" OrElse sepList = "" Then
     Redim result(0)
     result(0) = s
     Return
  End If
  Dim As Integer i, j, count = 0, empty = 0, length
  Dim As Integer position(Len(s) + 1)
  position(0) = 0

  For i = 0 To len(s) - 1
    For j = 0 to Len(sepList) - 1
      If s[i] = sepList[j] Then
        count += 1
        position(count) = i + 1
      End If
    Next j
  Next i

  Redim result(count)
  If count  = 0 Then
    result(0) = s
    Return
  End If

  position(count + 1) = len(s) + 1

  For i = 1 To count + 1
    length = position(i) - position(i - 1) - 1
    result(i - 1 - empty) = Mid(s, position(i - 1) + 1, length)
    If removeEmpty Andalso CBool(length = 0) Then empty += 1
  Next

  If empty > 0 Then Redim Preserve result(count - empty)
End Sub

Function parseDate(dt As String, zone As String) As Double
  Dim result() As String
  split dt, " ", result(), True
  Dim As Long m, d, y, h, mn
  Dim am As Boolean
  Dim index As Integer
  Select Case Lcase(result(0))
    Case "january"    : m = 1
    Case "february"   : m = 2
    Case "march"      : m = 3
    Case "april"      : m = 4
    Case "may"        : m = 5
    Case "june"       : m = 6
    Case "july"       : m = 7
    Case "august"     : m = 8
    Case "september"  : m = 9
    Case "october"    : m = 10
    Case "november"   : m = 11
    Case "december"   : m = 12
  End Select
  d = ValInt(result(1))
  y = ValInt(result(2))
  result(3) = LCase(result(3))
  am = (Right(result(3), 2) = "am")
  index = Instr(result(3), ":")
  h = ValInt(Left(result(3), index - 1))
  If Not am Then
    h = h + 12
    If h = 24 Then h = 12
  End If
  mn = ValInt(Mid(result(3), index + 1, 2))
  zone = result(4)
  Return DateSerial(y, m, d) + TimeSerial(h, mn, 0)
End Function

Dim zone As String
Dim ds As Double = parseDate("March 7 2009 7:30pm EST", zone)
Print "Original Date/Time  : "; Format(ds, "mmmm d yyyy h:nnam/pm ") + "  " + zone
ds = DateAdd("h", 12, ds)
Print "12 hours later      : "; Format(ds, "mmmm d yyyy h:nnam/pm ") + "  " + zone
' add 5 hours to convert EST to UTC
ds = DateAdd("h", 5, ds)
Print "Equiv to Date/Time  : "; Format(ds, "mmmm d yyyy h:nnam/pm ") + " UTC"
Print
Print "Press any key to quit"
Sleep


### MMM dd yyyy h:mma ###
d = parseDate["March 7 2009 7:30pm EST"]
println[d + 12 hours -> Eastern]
println[d + 12 hours -> Switzerland]  // Extra credit


import time.{TimeZone, Date, SimpleDateFormat, Hour}

pattern = SimpleDateFormat( 'MMMM d yyyy h:mma zzz' )
date = pattern.parse( 'March 7 2009 7:30pm EST' )
later = Date( date.getTime() + 12 Hour )
println( pattern.format(later) )    // Eastern Daylight Time
pattern.setTimeZone( TimeZone.getTimeZone('America/Los_Angeles') )
println( pattern.format(later) )    // U.S. Pacific Time


package main

import (
    "fmt"
    "time"
)

const taskDate = "March 7 2009 7:30pm EST"
const taskFormat = "January 2 2006 3:04pm MST"

func main() {
    if etz, err := time.LoadLocation("US/Eastern"); err == nil {
        time.Local = etz
    }
    fmt.Println("Input:             ", taskDate)
    t, err := time.Parse(taskFormat, taskDate)
    if err != nil {
        fmt.Println(err)
        return
    }
    t = t.Add(12 * time.Hour)
    fmt.Println("+12 hrs:           ", t)
    if _, offset := t.Zone(); offset == 0 {
        fmt.Println("No time zone info.")
        return
    }
    atz, err := time.LoadLocation("US/Arizona")
    if err == nil {
        fmt.Println("+12 hrs in Arizona:", t.In(atz))
    }
}


import org.joda.time.*
import java.text.*

def dateString = 'March 7 2009 7:30pm EST'

def sdf = new SimpleDateFormat('MMMM d yyyy h:mma zzz')

DateTime dt = new DateTime(sdf.parse(dateString))

println (dt)
println (dt.plusHours(12))
println (dt.plusHours(12).withZone(DateTimeZone.UTC))


import qualified Data.Time.Clock.POSIX as P
import qualified Data.Time.Format as F

-- UTC from EST
main :: IO ()
main = print t2
  where
    t1 =
      F.parseTimeOrError
        True
        F.defaultTimeLocale
        "%B %e %Y %l:%M%P %Z"
        "March 7 2009 7:30pm EST"
    t2 = P.posixSecondsToUTCTime $ 12 * 60 * 60 + P.utcTimeToPOSIXSeconds t1


   CHARACTER date="March 7 2009 7:30pm EST", am_pm, result*20

   EDIT(Text=date, Parse=cMonth, GetPosition=next)
   month = 1 + EDIT(Text='January,February,March,April,May,June,July,August,September,October,November,December', Right=cMonth, Count=',' )
   READ(Text=date(next:)) day, year, hour, minute, am_pm
   hour = hour + 12*(am_pm == 'p')
   TIME(MOnth=month, Day=day, Year=year, Hour=hour, MInute=minute, TO, Excel=xls_day)
   WRITE(Text=result, Format="UWWW CCYY-MM-DD HH:mm") xls_day + 0.5
                   ! result = "Sun 2009-03-08 07:30"
 END


link datetime

procedure main()
write("input      = ",s := "March 7 2009 7:30pm EST" )
write("+12 hours  = ",SecToTZDateLine(s := TZDateLineToSec(s) + 12*3600,"EST"))
write("           = ",SecToTZDateLine(s,"UTC"))
write("           = ",SecToTZDateLine(s,"NST"))
end

procedure SecToTZDateLine(s,tz)   #: returns dateline + time zone given seconds
return NormalizedDate(SecToDateLine(s+\(_TZdata("table")[\tz|"UTC"]))||" "|| tz)
end

procedure TZDateLineToSec(s)  #: returns seconds given dateline (and time zone)
   return (
      NormalizedDate(s) ? (
         d  := tab(find("am"|"pm")+2),tab(many('\t ,')),
         tz := \_TZdata("table")[tab(0)]
         ),
      DateLineToSec(d) - tz)
end

procedure NormalizedDate(s)  #: returns a consistent dateline
static D,M
initial {
   D := ["Saturday","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday"]
   M := ["January","February","March","April","May","June",
         "July","August","September","October","November","December"]
   }

map(s) ? {                               # parse and build consistent dateline
   ds := 1(x := !D, =map(x)) | ""                                    # Weekday
   ds ||:= 1(", ", tab(many('\t ,')|&pos))
   ds ||:= 1(x := !M, =map(x))                 | fail                # Month
   ds ||:= 1(" ", tab(many('\t ,')|&pos))
   ds ||:= tab(many(&digits))                  | fail                # day
   ds ||:= 1(", ", tab(many('\t ,')))          | fail
   ds ||:= tab(many(&digits))                  | fail                # year
   ds ||:= 1(" ", tab(many('\t ,')))           | fail
   ds ||:= tab(many(&digits))||(=":"||tab(many(&digits))|&null) | fail # time
   ds ||:= 1(" ", tab(many('\t ,')|&pos))
   ds ||:= =("am"|"pm")                        | fail                # halfday
   ds ||:= 1(" ", tab(many('\t ,')|&pos))
   tz := map(=!_TZdata("list"),&lcase,&ucase)
   }

if ds[1] == "," then
   ds := SecToDateLine(DateLineToSec("Sunday"||ds))   # get IPL to fix weekday

return ds ||:=  " " || \tz|"UTC"
end

procedure _TZdata(x)    #: internal return TZ data (demo version incomplete)
static TZ,AZ
initial {
   TZ := table()
   AZ := []
   "UTC/0;ACDT/+10.5;CET/1;EST/-5;NPT/+5.75;NST/-3.5;PST/-8;" ?
      while (  a := tab(find("/")), move(1), o := tab(find(";")), move(1) ) do {
         TZ[map(a)] := TZ[a] := integer(3600*o)
         put(AZ,a,map(a))
         }
      every TZ[&null|""] := TZ["UTC"]
   }
return case x of { "list"  : AZ ; "table" : TZ }
end


require'dates'
months=: <;._2 tolower 0 :0
January
February
March
April
May
June
July
August
September
October
November
December
)

numbers=: _".' '"_`(1 [email protected]:-e.&(":i.10)@])`]}~
words=: [:;:@tolower' '"_`([email protected](tolower = toupper)@])`]}~
getyear=: >./@numbers
getmonth=: 1 + months <./@i. words
getday=: {[email protected](numbers -. getyear)
gethour=: (2 { numbers) + 12 * (<'pm') e. words
getminsec=: 2 {. 3}. numbers

getts=: getyear, getmonth, getday, gethour, getminsec
timeadd=: 1&[email protected]+&tsrep
deltaT=: (1 tsrep 0)&([ + [email protected]#@[ {. ])


import java.time.*;
import java.time.format.*;

class Main {
  public static void main(String args[]) {
    String dateStr = "March 7 2009 7:30pm EST";

    DateTimeFormatter df = new DateTimeFormatterBuilder()
				.parseCaseInsensitive()
				.appendPattern("MMMM d yyyy h:mma zzz")
				.toFormatter();

    ZonedDateTime after12Hours = ZonedDateTime.parse(dateStr, df).plusHours(12);

    System.out.println("Date: " + dateStr);
    System.out.println("+12h: " + after12Hours.format(df));

    ZonedDateTime after12HoursInCentralEuropeTime = after12Hours.withZoneSameInstant(ZoneId.of("CET"));
    System.out.println("+12h (in Central Europe): " + after12HoursInCentralEuropeTime.format(df));
  }
}


function add12hours(dateString) {

  // Get the parts of the date string
  var parts = dateString.split(/\s+/),
      date  = parts[1],
      month = parts[0],
      year  = parts[2],
      time  = parts[3];

  var hr    = Number(time.split(':')[0]),
      min   = Number(time.split(':')[1].replace(/\D/g,'')),
      ampm  = time && time.match(/[a-z]+$/i)[0],
      zone  = parts[4].toUpperCase();

  var months = ['January','February','March','April','May','June',
                'July','August','September','October','November','December'];
  var zones  = {'EST': 300, 'AEST': -600}; // Minutes to add to zone time to get UTC

  // Convert month name to number, zero indexed. Return if invalid month
  month = months.indexOf(month);
  if (month === -1) { return; }

  // Add 12 hours as specified. Add another 12 if pm for 24hr time
  hr += (ampm.toLowerCase() === 'pm') ? 24 : 12

  // Create a date object in local zone
  var localTime = new Date(year, month, date);
  localTime.setHours(hr, min, 0, 0);

  // Adjust localTime minutes for the time zones so it is now a local date
  // representing the same moment as the source date plus 12 hours
  localTime.setMinutes(localTime.getMinutes() + zones[zone] - localTime.getTimezoneOffset() );
  return localTime;
}

var inputDateString = 'March 7 2009 7:30pm EST';

console.log(
  'Input: ' + inputDateString + '\n' +
  '+12hrs in local time: ' + add12hours(inputDateString)
 );


"March 7 2009 7:30pm EST"
| strptime("%B %d %Y %I:%M%p %Z")
| .[3] += 12
| mktime | strftime("%B %d %Y %I:%M%p %Z")


using Dates

function main()
    dtstr = "March 7 2009 7:30pm" # Base.Dates doesn't handle "EST"
    cleandtstr = replace(dtstr, r"(am|pm)"i, "")
    dtformat = dateformat"U dd yyyy HH:MM"
    dtime = parse(DateTime, cleandtstr, dtformat) +
        Hour(12 * contains(dtstr, r"pm"i)) # add 12h for the pm
    println(Dates.format(dtime + Hour(12), dtformat))
end

main()


// version 1.0.6

import java.text.SimpleDateFormat
import java.util.*

fun main(args: Array<String>) {
    val dts  = "March 7 2009 7:30pm EST"
    val sdf  = SimpleDateFormat("MMMM d yyyy h:mma z")
    val dt   = sdf.parse(dts)
    val cal  = GregorianCalendar(TimeZone.getTimeZone("EST"))  // stay with EST
    cal.time = dt
    cal.add(Calendar.HOUR_OF_DAY, 12) // add 12 hours
    val fmt = "%tB %1\$td %1\$tY %1\$tl:%1\$tM%1\$tp %1\$tZ"
    println(fmt.format(cal)) // display new time

    // display time now in Mountain Standard Time which is 2 hours earlier than EST
    cal.timeZone = TimeZone.getTimeZone("MST")
    println(fmt.format(cal))
}


val .input = "March 7 2009 7:30pm -05:00"
val .iformat = "January 2 2006 3:04pm -07:00"   # input format
val .format = "January 2 2006 3:04pm MST"       # output format

val .d1 = toDateTime .input, .iformat
val .d2 = .d1 + dt/PT12H/
val .d3 = toDateTime .d2, "US/Arizona"
val .d4 = toDateTime .d2, ZLS
val .d5 = toDateTime .d2, "Z"
val .d6 = toDateTime .d2, "+02:30"
val .d7 = toDateTime .d2, "EST"

writeln "input string: ", .input
writeln "input format string: ", .iformat
writeln "output format string: ", .format
writeln()

writeln $"original: \.d1; (\.d1:dt.format;)"
writeln $"+12 hours: \.d2; (\.d2:dt.format;)"
writeln $"in Arizona: \.d3; (\.d3:dt.format;)"
writeln $"in local time zone: \.d4; (\.d4:dt.format;)"
writeln $"in UTC: \.d5; (\.d5:dt.format;)"
writeln $"+02:30 time zone: \.d6; (\.d6:dt.format;)"
writeln $"in EST: \.d7; (\.d7:dt.format;)"


local(date) = date('March 7 2009 7:30PM EST',-format='MMMM d yyyy h:mma z')
#date->add(-hour = 24)
#date->timezone = 'GMT'


----------------------------------------
-- Returns string representation of given date object in YYYY-MM-DD hh:mm:ii format
-- @param {date} dateObj
-- @returns {string}
----------------------------------------
on dateToDateTimeString (dateObj)
  str = ""
  s = string(dateObj.year)
  if s.length<4 then put "0000".char[1..4-s.length] before s
  put s after str
  s = string(dateObj.month)
  if s.length<2 then s = "0"&s
  put s after str
  s = string(dateObj.day)
  if s.length<2 then put "0" before s
  put s after str
  sec = dateObj.seconds
  s = string(sec / 3600)
  sec = sec mod 3600
  if s.length<2 then put "0" before s
  put s after str
  s = string(sec / 60)
  sec = sec mod 60
  if s.length<2 then put "0" before s
  put s after str
  s = string(sec)
  if s.length<2 then put "0" before s
  put s after str
  put ":" after char 12 of str
  put ":" after char 10 of str
  put " " after char 8 of str
  put "-" after char 6 of str
  put "-" after char 4 of str
  return str
end


str = string.lower( "March 7 2009 7:30pm EST" )

month = string.match( str, "%a+" )
if     month == "january"   then month = 1
elseif month == "february"  then month = 2
elseif month == "march"     then month = 3
elseif month == "april"     then month = 4
elseif month == "may"       then month = 5
elseif month == "june"      then month = 6
elseif month == "july"      then month = 7
elseif month == "august"    then month = 8
elseif month == "september" then month = 9
elseif month == "october"   then month = 10
elseif month == "november"  then month = 11
elseif month == "december"  then month = 12
end

strproc = string.gmatch( str, "%d+" )
day  = strproc()
year = strproc()
hour = strproc()
min  = strproc()

if string.find( str, "pm" ) then hour = hour + 12 end

print( os.date( "%c", os.time{ year=year, month=month, day=day, hour=hour, min=min, sec=0 } + 12 * 3600 ) )


twelve_hours := proc(str)
	local dt, zone;
	local months := ["January","February","March","April","May","June","July","August","September","October","November","December"];
	dt := StringTools:-ParseTime("%B %d %Y %l:%M%p", str);
	zone := StringTools:-RegSplit(" ", str)[-1];
	dt := Date(dt:-year, dt:-month, dt:-monthDay, dt:-hour, dt:-minute, timezone = zone);
	dt := dt + 12 * Unit(hours);
	printf("%s %d %d ", months[Month(dt)], DayOfMonth(dt), Year(dt));
	if (HourOfDay(dt) >= 12) then
		printf("%d:%dpm ", HourOfDay(dt)-12, Minute(dt));
	else
		printf("%d:%dam ", HourOfDay(dt), Minute(dt));
	end if;
	printf(TimeZone(dt));
end proc;


dstr = "March 7 2009 7:30pm EST";
DateString[DatePlus[dstr, {12, "Hour"}], {"DayName", " ", "MonthName", " ", "Day", " ", "Year", " ", "Hour24", ":", "Minute", "AMPM"}]


echo -ag $asctime($calc($ctime(March 7 2009 7:30pm EST)+43200))


/* NetRexx */
options replace format comments java crossref symbols binary

import java.text.SimpleDateFormat
import java.text.ParseException

runSample(arg)
return

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method manipulateDate(sampleDate, dateFmt, dHours = 0) private static
  formatter = SimpleDateFormat(dateFmt)
  msHours = dHours * 60 * 60 * 1000 -- hours in milliseconds
  day = formatter.parse(sampleDate)
  day.setTime(day.getTime() + msHours)
  formatted = formatter.format(day)
  return formatted

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method runSample(arg) private static
  do
    sampleDate = 'March 7 2009 7:30pm EST'
    dateFmt = "MMMM d yyyy h:mma z"
    say sampleDate
    say manipulateDate(sampleDate, dateFmt, 12)
  catch ex = Exception
    ex.printStackTrace()
  end
  return


import times

const Date = "March 7 2009 7:30pm EST"
echo "Original date is:        ", Date

var dt = Date.replace("EST", "-05:00").parse("MMMM d yyyy h:mmtt zzz")
echo "Original date in UTC is: ", dt.utc().format("MMMM d yyyy h:mmtt zzz")

dt = dt + initDuration(hours = 12)
echo "Date 12 hours later is:  ", dt.utc().format("MMMM d yyyy h:mmtt zzz")


  sampleDate = 'March 7 2009 7:30pm EST'

  Parse var sampleDate month day year time zone
  basedate = .DateTime~fromNormalDate(day month~left(3) year)
  basetime = .DateTime~fromCivilTime(time)
  -- this will give us this in a merged format...now we can add in the
  -- timezone informat
  mergedTime = (basedate + basetime~timeofday)~isoDate
  zone = .TimeZoneDataBase~getTimeZone(zone)

  finalTime = .DateTime~fromIsoDate(mergedTime, zone~datetimeOffset)

  say 'Original date:' finalTime~utcIsoDate
  say 'Result after adding 12 hours:' finalTime~addHours(12)~utcIsoDate
  say 'Result shifted to UTC:' finalTime~toTimeZone(0)~utcIsoDate
  say 'Result shifted to Pacific Standard Time:' finalTime~toTimeZone(.TimeZoneDataBase~getTimeZone('PST')~datetimeOffset)~utcIsoDate
  say 'Result shifted to NepalTime Time:' finalTime~toTimeZone(.TimeZoneDataBase~getTimeZone('NPT')~datetimeOffset)~utcIsoDate

-- a descriptor for timezone information
::class timezone
::method init
  expose code name offset altname region
  use strict arg code, name, offset, altname, region
  code~upper

::attribute code GET
::attribute name GET
::attribute offset GET
::attribute altname GET
::attribute region GET
::attribute datetimeOffset GET
  expose offset
  return offset * 60

-- our database of timezones
::class timezonedatabase
-- initialize the class object.  This occurs when the program is first loaded
::method init class
  expose timezones

  timezones = .directory~new
  -- extract the timezone data which is conveniently stored in a method
  data = self~instanceMethod('TIMEZONEDATA')~source

  loop line over data
    -- skip over the comment delimiters, blank lines, and the 'return'
    -- lines that force the comments to be included in the source
    if line = '/*' | line = '*/' | line = '' | line = 'return' then iterate
    parse var line '{' region '}'
    if region \= '' then do
       zregion = region
       iterate
    end
    else do
       parse var line abbrev . '!' fullname '!' altname . '!' offset .
       timezone = .timezone~new(abbrev, fullname, offset, altname, zregion)
       timezones[timezone~code] = timezone
    end
  end

::method getTimezone class
  expose timezones
  use strict arg code
  return timezones[code~upper]

-- this is a dummy method containing the timezone database data.
-- we'll access the source directly and extract the data held in comments
-- the two return statements force the comment lines to be included in the
-- source rather than processed as part of comments between directives
::method timeZoneData class private
return
/*
{Universal}
UTC  ! Coordinated Universal Time          !        !   0

{Europe}
BST  ! British Summer Time                 !        !  +1
CEST ! Central European Summer Time        !        !  +2
CET  ! Central European Time               !        !  +1
EEST ! Eastern European Summer Time        !        !  +3
EET  ! Eastern European Time               !        !  +2
GMT  ! Greenwich Mean Time                 !        !   0
IST  ! Irish Standard Time                 !        !  +1
KUYT ! Kuybyshev Time                      !        !  +4
MSD  ! Moscow Daylight Time                !        !  +4
MSK  ! Moscow Standard Time                !        !  +3
SAMT ! Samara Time                         !        !  +4
WEST ! Western European Summer Time        !        !  +1
WET  ! Western European Time               !        !   0

{North America}
ADT  ! Atlantic Daylight Time              ! HAA    !  -3
AKDT ! Alaska Daylight Time                ! HAY    !  -8
AKST ! Alaska Standard Time                ! HNY    !  -9
AST  ! Atlantic Standard Time              ! HNA    !  -4
CDT  ! Central Daylight Time               ! HAC    !  -5
CST  ! Central Standard Time               ! HNC    !  -6
EDT  ! Eastern Daylight Time               ! HAE    !  -4
EGST ! Eastern Greenland Summer Time       !        !   0
EGT  ! East Greenland Time                 !        !  -1
EST  ! Eastern Standard Time               ! HNE,ET !  -5
HADT ! Hawaii-Aleutian Daylight Time       !        !  -9
HAST ! Hawaii-Aleutian Standard Time       !        ! -10
MDT  ! Mountain Daylight Time              ! HAR    !  -6
MST  ! Mountain Standard Time              ! HNR    !  -7
NDT  ! Newfoundland Daylight Time          ! HAT    !  -2.5
NST  ! Newfoundland Standard Time          ! HNT    !  -3.5
PDT  ! Pacific Daylight Time               ! HAP    !  -7
PMDT ! Pierre & Miquelon Daylight Time     !        !  -2
PMST ! Pierre & Miquelon Standard Time     !        !  -3
PST  ! Pacific Standard Time               ! HNP,PT !  -8
WGST ! Western Greenland Summer Time       !        !  -2
WGT  ! West Greenland Time                 !        !  -3

{India and Indian Ocean}
IST  ! India Standard Time                 !        !  +5.5
PKT  ! Pakistan Standard Time              !        !  +5
BST  ! Bangladesh Standard Time            !        !  +6 -- Note: collision with British Summer Time
NPT  ! Nepal Time                          !        !  +5.75
BTT  ! Bhutan Time                         !        !  +6
BIOT ! British Indian Ocean Territory Time ! IOT    !  +6
MVT  ! Maldives Time                       !        !  +5
CCT  ! Cocos Islands Time                  !        !  +6.5
TFT  ! French Southern and Antarctic Time  !        !  +5
*/
return


use DateTime;
use DateTime::Format::Strptime 'strptime';
use feature 'say';

my $input =  'March 7 2009 7:30pm EST';
$input    =~ s{EST}{America/New_York};

say strptime('%b %d %Y %I:%M%p %O', $input)
        ->add(hours => 12)
        ->set_time_zone('America/Edmonton')
        ->format_cldr('MMMM d yyyy h:mma zzz');


include builtins\timedate.e
set_timedate_formats({"Mmmm d yyyy h:mmpm tz"})
timedate td = parse_date_string("March 7 2009 7:30pm EST")
atom twelvehours = timedelta(hours:=12)
td = adjust_timedate(td,twelvehours)
?format_timedate(td)
td = change_timezone(td,"ACDT")  -- extra credit
?format_timedate(td)
td = adjust_timedate(td,timedelta(days:=31*4))
?format_timedate(td)


<?php
$time = new DateTime('March 7 2009 7:30pm EST');
$time->modify('+12 hours');
echo $time->format('c');
?>


(de timePlus12 (Str)
   (use (@Mon @Day @Year @Time @Zone)
      (and
         (match
            '(@Mon " " @Day " " @Year " " @Time " " @Zone)
            (chop Str) )
         (setq @Mon (index (pack @Mon) *MonFmt))
         (setq @Day (format @Day))
         (setq @Year (format @Year))
         (setq @Time
            (case (tail 2 @Time)
               (("a" "m") ($tim (head -2 @Time)))
               (("p" "m") (+ `(time 12 0) ($tim (head -2 @Time))))
               (T ($tim @Time)) ) )
         (let? Date (date @Year @Mon @Day)
            (when (>= (inc '@Time `(time 12 0)) 86400)
               (dec '@Time 86400)
               (inc 'Date) )
            (pack (dat$ Date "-") " " (tim$ @Time T) " " @Zone) ) ) ) )


> (Calendar.dwim_time("March 7 2009 7:30pm EST")+Calendar.Hour()*12)->set_timezone("CET")->format_ext_time();
Result: "Saturday, 7 March 2009 12:30:00"


/* The PL/I date functions handle dates and time in 49             */
/* different formats, but not that particular one.  For any of the */
/* standard formats, the following date manipulation will add */
/* 12 hours to the current date/time. */

seconds = SECS(DATETIME());
seconds = seconds + 12*60*60;
put list (SECSTODATE(seconds));


$date = [DateTime]::Parse("March 7 2009 7:30pm -5" )
write-host $date
write-host $date.AddHours(12)
write-host [TimeZoneInfo]::ConvertTimeBySystemTimeZoneId($date.AddHours(12),"Vladivostok Standard Time")


EnableExplicit

Procedure.i ToPBDate(Date$, *zone.String)
  Protected year, month, day, hour, minute
  Protected month$, temp$, time$, pm$, zone$
  month$ = StringField(date$, 1, " ")
  day = Val(StringField(date$, 2, " "))
  year = Val(StringField(date$, 3, " "))
  time$ = StringField(date$, 4, " ")
  zone$ = StringField(date$, 5, " ")

  Select month$
    Case "January"   : month = 1
    Case "February"  : month = 2
    Case "March"     : month = 3
    Case "April"     : month = 4
    Case "May"       : month = 5
    Case "June"      : month = 6
    Case "July"      : month = 7
    Case "August"    : month = 8
    Case "September" : month = 9
    Case "October"   : month = 10
    Case "November"  : month = 11
    Case "December"  : month = 12
  EndSelect

  hour = Val(StringField(time$, 1, ":"))
  temp$ = StringField(time$, 2, ":")
  minute = Val(Left(temp$, 2))
  pm$ = Right(temp$, 2)

  If pm$ = "am"
    If hour = 12 : hour = 0 : EndIf
  Else
    If hour <> 12 : hour + 12 : EndIf
  EndIf

  *zone\s = zone$
  ProcedureReturn Date(year, month, day, hour, minute, 0)
EndProcedure

Procedure.s FromPBDate(Date, zone$)
  Protected year$  = Str(Year(Date))
  Protected month = Month(Date)
  Protected day$ = Str(Day(Date))
  Protected hour = Hour(Date)
  Protected minute = Minute(Date)
  Protected month$, time$, pm$, result$

  Select month
    Case 1  :  month$ = "January"
    Case 2  :  month$ = "February"
    Case 3  :  month$ = "March"
    Case 4  :  month$ = "April"
    Case 5  :  month$ = "May"
    Case 6  :  month$ = "June"
    Case 7  :  month$ = "July"
    Case 8  :  month$ = "August"
    Case 9  :  month$ = "September"
    Case 10 :  month$ = "October"
    Case 11 :  month$ = "November"
    Case 12 :  month$ = "December"
  EndSelect

  If hour > 12
    hour - 12
    pm$ = "pm"
  ElseIf hour = 12
    pm$ = "pm"
  Else
    If hour = 0 : hour = 12 : EndIf
    pm$ = "am"
  EndIf

  time$ = Str(hour) + ":" + RSet(Str(minute), 2, "0") + pm$
  result$ = month$ + " " + day$ + " " + year$ + " " + time$ + " " + zone$
  ProcedureReturn result$
EndProcedure

Define date
Define date1$, date2$
Define zone.String

If OpenConsole()
  date1$ = "March 7 2009 7:30pm EST"
  PrintN("Starting date/time : " + date1$)
  date = ToPBDate(date1$, @zone)
  date = AddDate(date, #PB_Date_Hour, 12); add 12 hours
  date2$ = FromPBDate(date, zone\s)
  PrintN("12 hours later     : " + date2$)
  date = AddDate(date, #PB_Date_Hour, 5); adjust to GMT
  date2$ = FromPBDate(date, "GMT")
  PrintN("Or in GMT timezone : " + date2$)
  PrintN("")
  PrintN("Press any key to close the console")
  Repeat: Delay(10) : Until Inkey() <> ""
  CloseConsole()
EndIf


import datetime

def mt():
	datime1="March 7 2009 7:30pm EST"
	formatting = "%B %d %Y %I:%M%p "
	datime2 = datime1[:-3]  # format can't handle "EST" for some reason
	tdelta = datetime.timedelta(hours=12)		# twelve hours..
	s3 = datetime.datetime.strptime(datime2, formatting)
	datime2 = s3+tdelta
	print datime2.strftime("%B %d %Y %I:%M%p %Z") + datime1[-3:]

mt()


time <- strptime("March 7 2009 7:30pm EST", "%B %d %Y %I:%M%p %Z") # "2009-03-07 19:30:00"
isotime <- ISOdatetime(1900 + time$year, time$mon, time$mday,
   time$hour, time$min, time$sec, "EST")                           # "2009-02-07 19:30:00 EST"
twelvehourslater <- isotime + 12 * 60 * 60                         # "2009-02-08 07:30:00 EST"
timeincentraleurope <- format(isotime, tz="CET", usetz=TRUE)       #"2009-02-08 01:30:00 CET"


#lang racket
(require srfi/19)

(define 12hours (make-time time-duration 0 (* 12 60 60)))

(define (string->time s)
  (define t (date->time-utc (string->date s "~B~e~Y~H~M")))
  (if (regexp-match "pm" s)
      (add-duration t 12hours)
      t))

(date->string
 (time-utc->date
  (add-duration
   (string->time "March 7 2009 7:30pm est" )
   12hours))
 "~a ~d ~b ~Y ~H:~M")


my @month = <January February March April May June July August September October November December>;
my %month = flat (@month Z=> ^12), (@month».substr(0,3) Z=> ^12), 'Sept' => 8;

grammar US-DateTime {
    rule TOP { <month> <day>','? <year>','? <time> <tz> }

    token month {
	(\w+)'.'?  { make %month{$0} // die "Bad month name: $0" }
    }

    token day { (\d ** 1..2) { make +$0 } }

    token year { (\d ** 1..4) { make +$0 } }

    token time {
	(\d ** 1..2) ':' (\d ** 2) \h* ( :i <[ap]> \.? m | '' )
	{
	    my $h = $0 % 12;
	    my $m = $1;
	    $h += 12 if $2 and $2.substr(0,1).lc eq 'p';
	    make $h * 60 + $m;
	}
    }

    token tz {  # quick and dirty for this task
        [
        |        EDT  { make -4 }
        | [ EST| CDT] { make -5 }
        | [ CST| MDT] { make -6 }
        | [ MST| PDT] { make -7 }
        | [ PST|AKDT] { make -8 }
        | [AKST|HADT] { make -9 }
        |  HAST
        ]
    }
}

$/ = US-DateTime.parse('March 7 2009 7:30pm EST') or die "Can't parse date";

my $year     = $<year>.ast;
my $month    = $<month>.ast;
my $day      = $<day>.ast;
my $hour     = $<time>.ast div 60;
my $minute   = $<time>.ast mod 60;
my $timezone = $<tz>.ast * 3600;

my $dt = DateTime.new(:$year, :$month, :$day, :$hour, :$minute, :$timezone).in-timezone(0);

$dt = $dt.later(hours => 12);

say "12 hours later, GMT: $dt";
say "12 hours later, PST: $dt.in-timezone(-8 * 3600)";


rebol [
	Title: "Date Manipulation"
	URL: http://rosettacode.org/wiki/Date_Manipulation
]

; Only North American zones here -- feel free to extend for your area.

zones: [
	NST -3:30 NDT -2:30 AST -4:00 ADT -3:00 EST -5:00 EDT -4:00
	CST -6:00 CDT -5:00 MST -7:00 MDT -6:00 PST -8:00 PDT -7:00 AKST -9:00
	AKDT -8:00 HAST -10:00 HADT -9:00]

read-time: func [
	text
	/local m d y t z
][
	parse load text [
		set m word! (m: index? find system/locale/months to-string m)
		set d integer!  set y integer!
		set t time!  set tz word!]
	to-date reduce [y m d t  zones/:tz]
]

print 12:00 + read-time "March 7 2009 7:30pm EST"


/*REXX program adds 12 hours to a  given date and time, displaying the before and after.*/
 aDate = 'March 7 2009 7:30pm EST'               /*the original or base date to be used.*/

parse var aDate mon dd yyyy hhmm tz .            /*obtain the various parts and pieces. */

  mins = time('M', hhmm, "C")                    /*get the number minutes past midnight.*/
  mins = mins + (12*60)                          /*add  twelve hours  to the  timestamp.*/
 nMins = mins // 1440                            /*compute number min into same/next day*/
  days = mins %  1440                            /*compute number of days added to dats.*/
aBdays = date('B', dd left(mon,3) yyyy)          /*number of base days since REXX epoch.*/
nBdays = aBdays + days                           /*now,  add the number of days added.  */
 nDate = date(,nBdays, 'B')                      /*calculate the new  date  (maybe).    */
 nTime = time('C', nMins, "M")                   /*    "      "   "   time     "        */

say aDate ' +  12 hours  ───► '  ndate ntime tz  /*display the new timestamp to console.*/
                                                 /*stick a fork in it,  we're all done. */


# Project : Date manipulation

load "stdlib.ring"
dateorigin = "March 7 2009 7:30pm EST"
monthname = "January February March April May June July August September October November December"
for i = 1 to 12
     if dateorigin[1] = monthname[i]
        monthnum = i
     ok
next
thedate = str2list(substr(dateorigin, " ", nl))
t = thedate[4]
t1 = substr(t,"pm", "")
t2 = substr(t1,":",".")
t3 = number(t2)
if right(t,2) = "pm"
   t3 = t3+ 12
ok
ap = "pm"
d = "07/03/2009"
if t3 + 12 > 24
  d = adddays("07/03/2009",1)
  ap = "am"
ok
see "Original - " + dateorigin + nl
see "Manipulated - " + d + " " + t1 + ap + nl


require 'time'
d = "March 7 2009 7:30pm EST"
t = Time.parse(d)
puts t.rfc2822
puts t.zone

new = t + 12*3600
puts new.rfc2822
puts new.zone

# another timezone
require 'rubygems'
require 'active_support'
zone = ActiveSupport::TimeZone['Beijing']
remote = zone.at(new)
# or, remote = new.in_time_zone('Beijing')
puts remote.rfc2822
puts remote.zone


theDate$ = "March 7 2009 7:30pm EST"

monthName$ = "January February March April May June July August September October November December"
for i = 1 to 12
  if word$(theDate$,1) = word$(monthName$,i) then monthNum = i			' turn month name to number
next i
d 	= val(date$(monthNum;"/";word$(theDate$,2);"/";word$(theDate$,3)))	' days since Jan 1 1901
t$	= word$(theDate$,4)				' get time from theDate$
t1$	= word$(t$,1,"pm")				' strip pm
t2$	= word$(t1$,1,":") + "." + word$(t1$,2,":")	' replace : with .
t	= val(t2$)
if right$(t$,2) = "pm" then t = t + 12
ap$	= "pm"
if t + 12 > 24 then
  d	= d + 1			' if over 24 hours add 1 to days since 1/1/1901
  ap$	= "am"
end if
print date$(d);" ";t1$;ap$


use chrono::prelude::*;
use chrono::Duration;

fn main() {
    // Chrono allows parsing time zone abbreviations like "EST", but
    // their meaning is ignored due to a lack of standardization.
    //
    // This solution compromises by augmenting the parsed datetime
    // with the timezone using the IANA abbreviation.
    let ndt =
        NaiveDateTime::parse_from_str("March 7 2009 7:30pm EST", "%B %e %Y %l:%M%P %Z").unwrap();

    // add TZ manually
    let dt = chrono_tz::EST.from_local_datetime(&ndt).unwrap();
    println!("Date parsed: {:?}", dt);

    let new_date = dt + Duration::hours(12);
    println!("+12 hrs in EST: {:?}", new_date);
    println!(
        "+12 hrs in CET: {:?}",
        new_date.with_timezone(&chrono_tz::CET)
    );
}


import java.text.SimpleDateFormat
import java.util.{Calendar, Locale, TimeZone}

object DateManipulation {
  def main(args: Array[String]): Unit = {
    val input="March 7 2009 7:30pm EST"
    val df=new SimpleDateFormat("MMMM d yyyy h:mma z", Locale.ENGLISH)
    val c=Calendar.getInstance()
    c.setTime(df.parse(input))

    c.add(Calendar.HOUR_OF_DAY, 12)
    println(df.format(c.getTime))

    df.setTimeZone(TimeZone.getTimeZone("GMT"))
    println(df.format(c.getTime))
  }
}


$ include "seed7_05.s7i";
  include "time.s7i";
  include "duration.s7i";

const func time: parseDate (in string: dateStri) is func
  result
    var time: aTime is time.value;
  local
    const array string: monthNames is [] ("January", "February", "March", "April",
        "May", "June", "July", "August", "September", "October", "November", "December");
    var array string: dateParts is 0 times "";
    var integer: month is 0;
    var string: timeStri is "";
  begin
    dateParts := split(dateStri, ' ');
    aTime.year := integer parse (dateParts[3]);
    aTime.month := 1;
    while monthNames[aTime.month] <> dateParts[1] do
      incr(aTime.month);
    end while;
    aTime.day := integer parse (dateParts[2]);
    timeStri := dateParts[4];
    if endsWith(timeStri, "am") then
      aTime.hour := integer parse (timeStri[.. pred(pos(timeStri, ':'))]);
    elsif endsWith(timeStri, "pm") then
      aTime.hour := integer parse (timeStri[.. pred(pos(timeStri, ':'))]) + 12;
    else
      raise RANGE_ERROR;
    end if;
    aTime.minute := integer parse (timeStri[succ(pos(timeStri, ':')) .. length(timeStri) - 2]);
    if dateParts[5] <> "UTC" then
      aTime.timeZone := 60 * integer parse (dateParts[5][4 ..]);
    end if;
  end func;

const proc: main is func
  local
    var time: aTime is time.value;
  begin
    aTime := parseDate("March 7 2009 7:30pm UTC-05");
    writeln("Given:         " <& aTime);
    aTime +:= 1 . DAYS;
    writeln("A day later:   " <& aTime);
    aTime := toUTC(aTime);
    writeln("In UTC:        " <& aTime);
  end func;


set date to "March 7 2009 7:30pm EST"
insert "[month name] [day] [year] [hour12]:[min][pm] [timeZoneID]" into the timeInputFormat

put date + 12 hours


var dt = frequire('DateTime::Format::Strptime')

var input =  'March 7 2009 7:30pm EST'
input.sub!('EST', 'America/New_York')

say dt.strptime('%b %d %Y %I:%M%p %O', input)   \
      .add(hours => 12)                         \
      .set_time_zone('America/Edmonton')        \
      .format_cldr('MMMM d yyyy h:mma zzz')


DateTime extend [
  setYear: aNum [ year := aNum ]
].

Object subclass: DateTimeTZ [
  |dateAndTime timeZoneDST timeZoneName timeZoneVar|

  DateTimeTZ class >> new [ ^(super basicNew) ]

  DateTimeTZ class >> readFromWithMeridian: aStream andTimeZone: aDict [
    |me|
    me := self new.
    ^ me initWithMeridian: aStream andTimeZone: aDict
  ]

  initWithMeridian: aStream andTimeZone: aDict [ |s|
    dateAndTime := DateTime readFrom: aStream copy.
    s := aStream collection asString.
    s =~ '[pP][mM]'
      ifMatched: [ :m |
        dateAndTime := dateAndTime + (Duration days: 0 hours: 12 minutes: 0 seconds: 0)
      ].
    aDict keysAndValuesDo: [ :k :v |
      s =~ k
        ifMatched: [ :x |
          dateAndTime := dateAndTime setOffset: (v at: 1).
	  timeZoneDST := (v at: 2) setOffset: (v at: 1).
	  timeZoneVar := (v at: 3).
	  timeZoneDST setYear: (self year). "ignore the year"
          timeZoneName := k
        ]
    ].
    ^ self
  ]

  setYear: aNum [ dateAndTime setYear: aNum ]
  year [ ^ dateAndTime year ]

  timeZoneName [ ^timeZoneName ]

  + aDuration [ |n|
    n := dateAndTime + aDuration.
    (n > timeZoneDST) ifTrue: [ n := n + timeZoneVar ].
    ^ (self copy dateTime: n)
  ]

  dateTime [ ^dateAndTime ]
  dateTime: aDT [ dateAndTime := aDT ]

].


-- March 7 2009 7:30pm EST

SELECT
TO_TIMESTAMP_TZ(
'March 7 2009 7:30pm EST',
'MONTH DD YYYY HH:MIAM TZR'
)
at TIME zone 'US/Eastern' orig_dt_time
FROM dual;

-- 12 hours later DST change

SELECT
(TO_TIMESTAMP_TZ(
'March 7 2009 7:30pm EST',
'MONTH DD YYYY HH:MIAM TZR'
)+
INTERVAL '12' HOUR)
at TIME zone 'US/Eastern' plus_12_dst
FROM dual;

-- 12 hours later no DST change
-- Arizona time, always MST

SELECT
(TO_TIMESTAMP_TZ(
'March 7 2009 7:30pm EST',
'MONTH DD YYYY HH:MIAM TZR'
)+
INTERVAL '12' HOUR)
at TIME zone 'US/Arizona' plus_12_nodst
FROM dual;


val smltime= fn input =>                                                      (* parse given format *)
let
 val mth::day::year::itime::t =  String.fields Char.isSpace input ;
 val tmp      =  String.fields (fn x=> x= #":") itime;
 val h        =  (valOf(Int.fromString (hd tmp) )) + (if  String.isSuffix "pm" (hd(tl tmp)) then 12 else 0 ) ;
 val ms       =  (String.extract (hd (tl tmp), 0 ,SOME 2))^":00" ;
 val mth      =  String.extract (mth,0,SOME 3)
in
                                                                              (* Sat is a dummy *)
  Date.fromString  ("Sat "^mth ^" " ^ (StringCvt.padLeft #"0" 2 day) ^ " "^(StringCvt.padLeft #"0" 2 (Int.toString h))^":" ^ ms^" "^ year )

end;

local
   val date2real =  Time.toReal o Date.toTime o valOf
   val onehour   =  date2real (  Date.fromString "Mon Jan 01 23:59:59 1973" ) - ( date2real (  Date.fromString "Mon Jan 01 22:59:59 1973" )) ;
in
   val hoursFrom = fn hours => fn from =>
      (Date.fromTimeLocal o Time.fromReal)( (  date2real from) +   hours *  onehour );
end;


import Foundation

let formatter = DateFormatter()

formatter.dateFormat = "MMMM dd yyyy hh:mma zzz"

guard let date = formatter.date(from: "March 7 2009 7:30pm EST") else {
  fatalError()
}

print(formatter.string(from: date))
print(formatter.string(from: date + 60 * 60 * 12))


set date "March 7 2009 7:30pm EST"
set epoch [clock scan $date -format "%B %d %Y %I:%M%p %z"]
set later [clock add $epoch 12 hours]
puts [clock format $later] ;# Sun Mar 08 08:30:00 EDT 2009
puts [clock format $later -timezone :Asia/Shanghai] ;# Sun Mar 08 20:30:00 CST 2009


epoch=$(date -d 'March 7 2009 7:30pm EST +12 hours' +%s)
date -d @$epoch
TZ=Asia/Shanghai date -d @$epoch


import "/date" for Date

var fmt = "mmmm| |d| |yyyy| |H|:|MM|am| |zz|"
var d = Date.parse("March 7 2009 7:30pm EST", fmt)
Date.default = fmt
System.print("Original date/time : %(d)")
d = d.addHours(12)
System.print("12 hours later     : %(d)")
// Adjust to MST say
d = d.adjustTime("MST")
System.print("Adjusted to MST    : %(d)")


var Date=Time.Date;
fcn add12h(dt){
   re:=RegExp(0'|(\w+)\s+(\d+)\s+(\d+)\ +(.+)\s|);
   re.search(dt);
   _,M,D,Y,hms:=re.matched;    //"March","7","2009","7:30pm"
   M=Date.monthNames.index(M); //3
   h,m,s:=Date.parseTime(hms); //19,30,0
   dti:=T(Y,M,D, h,m,s).apply("toInt");
   Y,M,D, h,m,s=Date.addHMS(dti,12);
   "%s %d %d %s".fmt(Date.monthNames[M],D,Y,Date.toAMPMString(h,m));
}


*        Day of the week           06/07/2016
DOW      CSECT
         USING  DOW,R15            base register
         LA     R6,2008            year=2008
LOOP     C      R6,=F'2121'        do year=2008 to 2121
         BH     ELOOP              .
         LR     R7,R6              y=year
         LA     R8,12              m=12
         LA     R9,25              d=25
         C      R8,=F'3'           if m<3
         BNL    MGE3               then
         LA     R8,12(R8)            m=m+12
         BCTR   R7,0                 y=y-1
MGE3     LR     R10,R7             y
         SRDA   R10,32             .
         D      R10,=F'100'        r=y//100 ; l=y/100
         LR     R3,R8              m
         LA     R3,1(R3)           m+1
         M      R2,=F'26'          *26
         D      R2,=F'10'          /10
         AR     R3,R9              +d
         AR     R3,R10             +r
         LR     R2,R10             r
         SRA    R2,2               /4
         AR     R2,R3              (d+(m+1)*26/10+r+r/4
         LR     R3,R11             l
         SRA    R3,2               /4
         AR     R2,R3              (d+(m+1)*26/10+r+r/4+l/4
         LA     R5,5               5
         MR     R4,R11             *l
         AR     R2,R5              (d+(m+1)*26/10+r+r/4+l/4+5*l)
         SRDA   R2,32              .
         D      R2,=F'7'           w=(d+(m+1)*26/10+r+r/4+l/4+5*l)//7
         C      R2,=F'1'           if w=1  (sunday)
         BNE    WNE1               then
         XDECO  R6,PG                edit year
         XPRNT  PG,12                print year
WNE1     LA     R6,1(R6)           year=year+1
         B      LOOP               next year
ELOOP    BR     R14                exit
PG       DS     CL12               buffer
         YREGS
         END    DOW


report zday_of_week
data: lv_start type i value 2007,
      lv_n type i value 114,
      lv_date type sy-datum,
      lv_weekday type string,
      lv_day type c,
      lv_year type n length 4.

write 'December 25 is a Sunday in: '.
do lv_n times.
   lv_year = lv_start + sy-index.
   concatenate lv_year '12' '25' into lv_date.
   call function 'DATE_COMPUTE_DAY'
    exporting date = lv_date
    importing day  = lv_day.

   select single langt from t246 into lv_weekday
     where sprsl = sy-langu and
     wotnr = lv_day.

   if lv_weekday eq 'Sunday'.
     write / lv_year.
   endif.
enddo.


Byte FUNC DayOfWeek(BYTE day, month CARD year BYTE century)
CARD weekday
BYTE ARRAY index=[0 3 2 5 0 3 5 1 4 6 2 4]

IF year < 100  THEN
   year = year + century * 100
FI

IF year < 1753 THEN RETURN(7) FI

IF month < 3 THEN
   year==-1
FI

month = index(month-1)
weekday=year + year/4 - year/100 + year/400 + month + day
weekday = weekday MOD 7
RETURN (weekday)

PROC main()
CARD y
PrintE("December 25 is a Sunday in:")
FOR y = 2008 to 2121
DO
IF DayOfWeek(25, 12, y)=0 THEN
PrintCE(y)
FI
OD
RETURN


with Ada.Calendar.Formatting;  use Ada.Calendar.Formatting;
with Ada.Text_IO;              use Ada.Text_IO;

procedure Yuletide is
begin
   for Year in 2008..2121 loop
      if Day_Of_Week (Time_Of (Year, 12, 25)) = Sunday then
         Put_Line (Image (Time_Of (Year, 12, 25)));
      end if;
   end loop;
end Yuletide;


# example from: http://www.xs4all.nl/~jmvdveer/algol.html - GPL #
INT sun=0 # , mon=1, tue=2, wed=3, thu=4, fri=5, sat=6 #;

PROC day of week = (INT year, month, day) INT: (
  # Day of the week by Zeller’s Congruence algorithm from 1887 #
  INT y := year, m := month, d := day, c;
  IF m <= 2 THEN
    m +:= 12; y -:= 1
  FI;
  c := y OVER 100;
  y %*:= 100;
  (d - 1 + ((m + 1) * 26) OVER 10 + y + y OVER 4 + c OVER 4 - 2 * c) MOD 7
);

test:(
  print("December 25th is a Sunday in:");
  FOR year FROM 2008 TO 2121 DO
    INT wd = day of week(year, 12, 25);
    IF wd = sun THEN print(whole(year,-5)) FI
  OD;
  new line(stand out)
)


begin % find years where Christmas day falls on a Sunday %
    integer procedure Day_of_week ( integer value d, m, y );
        begin
            integer j, k, mm, yy;
            mm := m;
            yy := y;
            if mm <= 2 then begin
                mm := mm + 12;
                yy := yy - 1;
            end if_m_le_2;
            j := yy div 100;
            k := yy rem 100;
            (d + ( ( mm + 1 ) * 26 ) div 10 + k + k div 4 + j div 4 + 5 * j ) rem 7
        end Day_of_week;
    write( "25th of December is a Sunday in" );
    for year := 2008 until 2121 do begin
        integer day;
        day := Day_of_week( 25, 12, year );
        if day = 1 then writeon( I_W := 5, S_W := 0, year );
    end for_year
end.


BEGIN

% CALCULATE P MOD Q %
INTEGER FUNCTION MOD(P, Q);
INTEGER P, Q;
BEGIN
   MOD := P - Q * (P / Q);
END;

COMMENT
  RETURN DAY OF WEEK (SUN=0, MON=1, ETC.) FOR A GIVEN
  GREGORIAN CALENDAR DATE USING ZELLER'S CONGRUENCE;
INTEGER FUNCTION DAYOFWEEK(MO, DA, YR);
INTEGER MO, DA, YR;
BEGIN
  INTEGER Y, C, Z;
  IF MO < 3 THEN
    BEGIN
      MO := MO + 10;
      YR := YR - 1;
    END
  ELSE MO := MO - 2;
  Y := MOD(YR, 100);
  C := YR / 100;
  Z := (26 * MO - 2) / 10;
  Z := Z + DA + Y + (Y / 4) + (C /4) - 2 * C + 777;
  DAYOFWEEK := MOD(Z, 7);
END;

% MAIN PROGRAM STARTS HERE %
INTEGER YEAR, SUNDAY;
SUNDAY := 0;
WRITE("CHRISTMAS WILL FALL ON A SUNDAY IN THESE YEARS:");
FOR YEAR := 2008 STEP 1 UNTIL 2121 DO
  BEGIN
    IF DAYOFWEEK(12, 25, YEAR) = SUNDAY THEN
       WRITE(YEAR);
  END;

END


⍝ Based on the simplified calculation of Zeller's congruence, since Christmas is after March 1st, no adjustment is required.
⎕IO ← 0              ⍝ Indices are 0-based
y ← 2008 + ⍳114      ⍝ Years from 2008 to 2121
⍝ Simplified Zeller function operating on table of dates formatted as 114 rows and 3 columns of (day, month, year)
⍝ 0 = Saturday, 1 = Sunday, 2 = Monday, 3 = Tuesday, 4 = Wednesday, 5 = Thursday, 6 = Friday
zeller ← { 7 | +/ (((1↑⍴⍵),6)⍴1 1 1 1 ¯1 1) × ⌊(((⍴⍵)⍴1 13 1)×⍵+(⍴⍵)⍴0 1 0)[;0 1 2 2 2 2]÷((1↑⍴⍵),6)⍴1 5 1 4 100 400 }
result ← (1 = zeller 25,[1]12,[0.5]y) / y


set ChristmasSundays to {}
set Christmas to (current date)
set month of Christmas to December
set day of Christmas to 25
repeat with |year| from 2008 to 2121
	set year of Christmas to |year|
	if weekday of Christmas is Sunday then set end of ChristmasSundays to |year|
end repeat
ChristmasSundays


(= day-names '(Sunday Monday Tuesday Wednesday Thursday Friday Saturday))
(= get-weekday-num (fn (year month day)
   (= helper '(0 3 2 5 0 3 5 1 4 6 2 4))
   (if (< month 3) (= year (- year 1)))
   (mod (+ year (helper (- month 1)) day
        (apply + (map [trunc (/ year _)] '(4 -100 400))))
   7)))
(= get-weekday-name (fn (weekday-num) (day-names weekday-num)))


print select 2008..2121 'year [
    "Sunday" = get to :date.format:"dd-MM-YYYY" ~"25-12-|year|" 'Day
]


year = 2008
stop = 2121

While year <= stop {
 FormatTime, day,% year 1225, dddd
 If day = Sunday
  out .= year "`n"
 year++
}
MsgBox,% out


#include <date.au3>
Const $iSunday = 1
For $iYear = 2008 To 2121 Step 1
   If $iSunday = _DateToDayOfWeek($iYear, 12, 25) Then
     ConsoleWrite(StringFormat($iYear & "\n"))
   EndIf
Next


# syntax: GAWK -f DAY_OF_THE_WEEK.AWK
# runtime does not support years > 2037 on my 32-bit Windows XP O/S
BEGIN {
    for (i=2008; i<=2121; i++) {
      x = strftime("%Y/%m/%d %a",mktime(sprintf("%d 12 25 0 0 0",i)))
      if (x ~ /Sun/) { print(x) }
    }
}


Declare Function modulo(x As Double, y As Double) As Double
Declare Function wd(m As Double, d As Double, y As Double) As Integer

Cls
Dim yr As Double
For yr = 2008 To 2121
	If wd(12,25,yr) = 1 Then
		Print "Dec " & 25 & ", " & yr
	EndIf
Next
Sleep

Function modulo(x As Double, y As Double) As Double
	If y = 0 Then
		Return x
	Else
		Return x - y * Int(x / y)
	End If
End Function

Function wd(m As Double, d As Double, y As Double) As Integer
	If m = 1 Or m = 2 Then
		m += 12
		y-= 1
	End If
	Return modulo(365 * y + Fix(y / 4) - Fix(y / 100) + Fix(y / 400) + d  + Fix((153 * m + 8) / 5), 7) + 1
End Function

Dec 25, 2011
Dec 25, 2016
Dec 25, 2022
Dec 25, 2033
Dec 25, 2039
Dec 25, 2044
Dec 25, 2050
Dec 25, 2061
Dec 25, 2067
Dec 25, 2072
Dec 25, 2078
Dec 25, 2089
Dec 25, 2095
Dec 25, 2101
Dec 25, 2107
Dec 25, 2112
Dec 25, 2118


:: Day of the Week task from Rosetta Code
:: Batch File Implementation
:: Question: In what years between 2008 and 2121 will the 25th of December be a Sunday?
:: Method: Zeller's Rule

@echo off
rem set month code for December
set mon=33
rem set day number
set day=25

for /L %%y in (2008,1,2121) do (
   setlocal enabledelayedexpansion
   set /a "a=%%y/100"
   set /a "b=%%y-(a*100)"
   set /a "weekday=(day+mon+b+(b/4)+(a/4)+(5*a))%%7"
   if "!weekday!"=="1" echo(Dec 25, %%y is a Sunday.
   endlocal
)
pause
exit /b 0


      INSTALL @lib$+"DATELIB"

      FOR year% = 2008 TO 2121
        IF FN_dow(FN_mjd(25, 12, year%)) = 0 THEN
          PRINT "Christmas Day is a Sunday in "; year%
        ENDIF
      NEXT


scale = 0

/*
 * Returns day of week (0 to 6) for year, month m, day d in proleptic
 * Gregorian calendar. Sunday is 0. Assumes y >= 1, scale = 0.
 */
define w(y, m, d) {
	auto a

	/* Calculate Zeller's congruence. */
	a = (14 - m) / 12
	m += 12 * a
	y -= a
	return ((d + (13 * m + 8) / 5 +			\
		 y + y / 4 - y / 100 + y / 400) % 7)
}

for (y = 2008; y <= 2121; y++) {
	/* If December 25 is a Sunday, print year. */
	if (w(y, 12, 25) == 0) y
}
quit


{ Calculate day of week in proleptic Gregorian calendar. Sunday == 0. }
    ( wday
    =   year month day adjustment mm yy
      .   !arg:(?year,?month,?day)
        & div$(14+-1*!month,12):?adjustment
        & !month+12*!adjustment+-2:?mm
        & !year+-1*!adjustment:?yy
        &   mod
          $ (   !day
              + div$(13*!mm+-1,5)
              + !yy
              + div$(!yy,4)
              + -1*div$(!yy,100)
              + div$(!yy,400)
            , 7
            )
    )
& 2008:?y
&   whl
  ' ( !y:~>2121
    & (   wday$(!y,12,25):0
        & put$(str$(!y "-12-25\n"))
      |
      )
    & 1+!y:?y
    )
& done;


#include <stdio.h>

/* Calculate day of week in proleptic Gregorian calendar. Sunday == 0. */
int wday(int year, int month, int day)
{
	int adjustment, mm, yy;

	adjustment = (14 - month) / 12;
	mm = month + 12 * adjustment - 2;
	yy = year - adjustment;
	return (day + (13 * mm - 1) / 5 +
		yy + yy / 4 - yy / 100 + yy / 400) % 7;
}

int main()
{
	int y;

	for (y = 2008; y <= 2121; y++) {
		if (wday(y, 12, 25) == 0) printf("%04d-12-25\n", y);
	}

	return 0;
}


using System;

class Program
{
    static void Main(string[] args)
    {
        for (int i = 2008; i <= 2121; i++)
        {
            DateTime date = new DateTime(i, 12, 25);
            if (date.DayOfWeek == DayOfWeek.Sunday)
            {
                Console.WriteLine(date.ToString("dd MMM yyyy"));
            }
        }
    }
}


#include <boost/date_time/gregorian/gregorian.hpp>
#include <iostream>

int main( ) {
   using namespace boost::gregorian ;

   std::cout
      << "Yuletide holidays must be allowed in the following years:\n" ;
   for ( int i = 2008 ; i < 2121 ; i++ ) {
      greg_year gy = i ;
      date d  ( gy, Dec , 25 ) ;
      if ( d.day_of_week( ) == Sunday ) {
	 std::cout << i << std::endl ;
      }
   }
   std::cout << "\n" ;
   return 0 ;
}


(import '(java.util GregorianCalendar))
(defn yuletide [start end]
	    (filter #(= (. (new GregorianCalendar %
			 (. GregorianCalendar DECEMBER) 25) get (. GregorianCalendar DAY_OF_WEEK))
		 (. GregorianCalendar SUNDAY)) (range start (inc end))))

(yuletide 2008 2121)


weekday = proc (d: date) returns (int)
    y: int := d.year
    m: int := d.month
    if m<3
        then y, m := y-1, m+10
        else m := m-2
    end
    c: int := y/100
    y := y//100
    z: int := (26*m-2)/10 + d.day + y + y/4 + c/4 - 2*c + 777
    return(z//7)
end weekday

start_up = proc ()
    po: stream := stream$primary_output()
    for year: int in int$from_to(2008, 2121) do
        if weekday(date$create(25, 12, year, 0, 0, 0))=0 then
            stream$putl(po, int$unparse(year))
        end
    end
end start_up


       program-id. dec25.
       data division.
       working-storage section.
       1 work-date.
        2 yr pic 9(4) value 2008.
        2 mo-da pic 9(4) value 1225. *> Dec 25
       1 wk-date redefines work-date pic 9(8).
       1 binary.
        2 int-date pic 9(8).
        2 dow pic 9(4).
       procedure division.
           perform varying yr from 2008 by 1
           until yr > 2121
               compute int-date = function integer-of-date (wk-date)
               compute dow = function mod ((int-date - 1) 7) + 1
               if dow = 7  *> Sunday = 7 per ISO 8601 and ISO 1989
                   display yr
               end-if
           end-perform
           stop run
           .
       end program dec25.


december = 11 # gotta love Date APIs :)
sunday = 0
for year in [2008..2121]
  xmas = new Date year, december, 25
  console.log year if xmas.getDay() is sunday


<cfloop from = "2008" to = "2121" index = "i">
    <cfset myDate = createDate(i, 12, 25) />
    <cfif dayOfWeek(myDate) eq 1>
        December 25th falls on a Sunday in <cfoutput>#i#</cfoutput><br />
    </cfif>
</cfloop>


(loop for year from 2008 upto 2121
   when (= 6 (multiple-value-bind
                   (second minute hour date month year day-of-week dst-p tz)
                 (decode-universal-time (encode-universal-time 0 0 0 25 12 year))
               (declare (ignore second minute hour date month year dst-p tz))
               day-of-week))
     collect year)


MODULE DayOfWeek;
IMPORT DevCommanders, TextMappers, Dates, StdLog;

PROCEDURE XmastOnSun(s,e: INTEGER);
VAR
	i: INTEGER;
	d: Dates.Date;
BEGIN
	i := s;d.day := 25;d.month := 12;
	WHILE i < e DO
		d.year := i;
		IF Dates.DayOfWeek(d) = Dates.sunday THEN
			StdLog.Int(i);StdLog.Ln
		END;
		INC(i)
	END
END XmastOnSun;

PROCEDURE Do*;
VAR
	s: TextMappers.Scanner;
	r: ARRAY 2 OF INTEGER;
	i: INTEGER;
BEGIN
	s.ConnectTo(DevCommanders.par.text);
	s.SetPos(DevCommanders.par.beg);
	s.Scan;i := 0;
	WHILE ~s.rider.eot DO
		IF s.type = TextMappers.int THEN
			r[i] := s.int; INC(i)
		END;
		s.Scan
	END;
	XmastOnSun(r[0],r[1]);
END Do;

END DayOfWeek.


include "cowgol.coh";

sub weekday(year: uint16, month: uint8, day: uint8): (wd: uint8) is
    if month < 3 then
        month := month + 10;
        year := year - 1;
    else
        month := month - 2;
    end if;
    var c := year / 100;
    var y := year % 100;
    var z := (26 * month as uint16 - 2) / 10;
    z := z + day as uint16 + y + (y / 4) + (c / 4) - 2 * c + 777;
    wd := (z % 7) as uint8;
end sub;

var year: uint16 := 2008;
while year <= 2121 loop
    if weekday(year, 12, 25) == 0 then
        print_i16(year);
        print_nl();
    end if;
    year := year + 1;
end loop;


void main() {
    import std.stdio, std.range, std.algorithm, std.datetime;

    writeln("Christmas comes on a Sunday in the years:\n",
            iota(2008, 2122)
            .filter!(y => Date(y, 12, 25).dayOfWeek == DayOfWeek.sun));
}


procedure IsXmasSunday(fromyear, toyear: integer);
var
i: integer;
TestDate: TDateTime;
outputyears: string;
begin
outputyears := '';
  for i:= fromyear to toyear do
  begin
    TestDate := EncodeDate(i,12,25);
    if dayofweek(TestDate) = 1 then
    begin
      outputyears := outputyears + inttostr(i) + ' ';
    end;
  end;
  //CONSOLE
  //writeln(outputyears);
  //GUI
  form1.label1.caption := outputyears;
end;


proc nonrec weekday(word y, m, d) byte:
    word c;
    if m<3 then
        m := m+10;
        y := y+1
    else
        m := m-2
    fi;
    c := y/100;
    y := y%100;
    ((26 * m - 2)/10 + d + y + y/4 + c/4 - 2*c + 777) % 7
corp

proc nonrec main() void:
    word year;
    for year from 2008 upto 2121 do
        if weekday(year, 12, 25)=0 then
            writeln(year)
        fi
    od
corp