# Copyright (C) 1995, David Muir Sharnoff

#package Time::CTime;
## This is release 95.10.01.00
#
#=head1 NAME
#
#Time::CTime -- format times ala POSIX asctime
#
#=head1 SYNOPSIS
#
#	use Time::CTime
# 	print ctime(time);
#	print asctime(timelocal(time));
#	print strftime(template, localtime(time)); 
#
#=head2 strftime conversions
#
#	%%	PERCENT
#	%a	day of the week abbr
#	%A	day of the week
#	%b	month abbr
#	%B 	month
#	%c 	ctime format: Sat Nov 19 21:05:57 1994
#	%d 	numeric day of the month
#	%e 	DD
#	%D 	MM/DD/YY
#	%h 	month abbr
#	%H 	hour, 24 hour clock, leading 0's)
#	%I 	hour, 12 hour clock, leading 0's)
#	%j 	day of the year
#	%k 	hour
#	%l 	hour, 12 hour clock
#	%m 	month number, starting with 1
#	%M 	minute, leading 0's
#	%n 	NEWLINE
#	%o	ornate day of month -- "1st", "2nd", "25th", etc.
#	%p 	AM or PM 
#	%r 	time format: 09:05:57 PM
#	%R 	time format: 21:05
#	%S 	seconds, leading 0's
#	%t 	TAB
#	%T 	time format: 21:05:57
#	%U 	week number, Sunday as first day of week
#	%w 	day of the week, numerically, Sunday == 0
#	%W 	week number, Monday as first day of week
#	%x 	date format: 11/19/94
#	%X 	time format: 21:05:57
#	%y	year (2 digits)
#	%Y	year (4 digits)
#	%Z 	timezone in ascii. eg: PST
#
#=head1 DESCRIPTION
#
#This module provides routines to format dates.  They correspond 
#to the libc routines.  &strftime() supports a pretty good set of
#coversions -- more than most C libraries.
#
#strftime supports a pretty good set of conversions.  
#
#The POSIX module has very similar functionality.  You should consider
#using it instead if you do not have allergic reactions to system 
#libraries.
#
#=head1 GENESIS
#
#Written by David Muir Sharnoff <muir@idiom.com>.
#
#Tthe starting point for this package was a posting by 
#Paul Foley <paul@ascent.com> 
#
#=cut
#
#require 5.000;

#use Time::Timezone;
#require Exporter;
#@ISA = qw(Exporter);
#@EXPORT = qw(ctime asctime strftime);
#@EXPORT_OK = qw(asctime_n ctime_n);

require "Timezone.pm.pl";

CONFIG: {
    #@DoW = 	   qw(Sun Mon Tue Wed Thu Fri Sat);
    #@DayOfWeek =   qw(Sunday Monday Tuesday Wednesday Thursday Friday Saturday);
    #@MoY = 	   qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
    #@MonthOfYear = qw(January February March April May June 
#		      July August September October November December);

    @DoW = 	   ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');
    @DayOfWeek =   ('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
    @MoY = 	   ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
    @MonthOfYear = ('January', 'February', 'March', 'April', 'May', 'June', 
		      'July', 'August', 'September', 'October', 'November', 'December');
  
  
    %strftime_conversion = (split("\t",<<''));
	must have leading tab for split
	%	'%'
	a	$DoW[$wday]
	A	$DayOfWeek[$wday]
	b	$MoY[$mon]
	B	$MonthOfYear[$mon]
	c	&asctime_n($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst, "")
	d	sprintf("%02d", $mday);
	D	sprintf("%02d/%02d/%02d", $mon+1, $mday, $year%100)
	e	sprintf("%2d", $mday);
	h	$MoY[$mon]
	H	sprintf("%02d", $hour)
	I	sprintf("%02d", $hour % 12 || 12)
	j	sprintf("%03d", $yday + 1)
	k	sprintf("%2d", $hour);
	l	sprintf("%2d", $hour % 12 || 12)
	m	sprintf("%02d", $mon+1);
	M	sprintf("%02d", $min)
	n	"\n"
	o	sprintf("%d%s", $mday, (($mday < 20 && $mday > 3) ? 'th' : ($mday%10 == 1 ? "st" : ($mday%10 == 2 ? "nd" : ($mday%10 == 3 ? "rd" : "th")))))
	p	$hour > 11 ? "PM" : "AM"
	r	sprintf("%02d:%02d:%02d %s", $hour % 12 || 12, $min, $sec, $hour > 11 ? 'PM' : 'AM')
	R	sprintf("%02d:%02d", $hour, $min)
	S	sprintf("%02d", $sec)
	t	"\t"
	T	sprintf("%02d:%02d:%02d", $hour, $min, $sec)
	U	&wkyr(0, $wday, $yday)
	w	$wday
	W	&wkyr(1, $wday, $yday)
	y	$year%100
	Y	$year%100 + ( $year%100<70 ? 2000 : 1900)
	x	sprintf("%02d/%02d/%02d", $mon + 1, $mday, $year%100)
	X	sprintf("%02d:%02d:%02d", $hour, $min, $sec)
	Z	&tz2zone(undef,undef,$isdst)


}

sub asctime_n {
    local($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst, $TZname) = @_;
    $year += ($year < 70) ? 2000 : 1900;
    $TZname .= ' ' 
	if $TZname;
    sprintf("%s %s %2d %2d:%02d:%02d %s%4d",
	  $DoW[$wday], $MoY[$mon], $mday, $hour, $min, $sec, $TZname, $year);
}

sub asctime
{
    return &asctime_n(@_)."\n";
}

# is this formula right?
sub wkyr {
    local($wstart, $wday, $yday) = @_;
    $wday = ($wday + 7 - $wstart) % 7;
    return int(($yday - $wday + 13) / 7 - 1);
}

# ctime($time)

sub ctime {
    local($time) = @_;
    &asctime(localtime($time), &tz2zone(undef,$time));
}

sub ctime_n {
    local($time) = @_;
    &asctime_n(localtime($time), &tz2zone(undef,$time));
}

# strftime($template, @time_struct)
#
# Does not support locales

sub strftime {			
    local($template, $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = @_;

    $template =~ s/%([%aAbBcdDehHIjklmMnopQrRStTUwWxXyYZ])/$strftime_conversion{$1}/eeg;
    die $@ if $@;
    return $template;
}

1;