9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
From: lucio@proxima.alt.za
To: 9fans@9fans.net
Subject: Re: [9fans] silly question
Date: Tue,  2 Sep 2014 10:27:56 +0200	[thread overview]
Message-ID: <1b89f632938db085db4f9b3fa706bc5e@proxima.alt.za> (raw)
In-Reply-To: <02adc2378671d0fb6129e699821979e0@quintile.net>

> gawk has date, strftime and mktime but Brian's does not.

I hacked a version of strftime() for my own use, I don't know if it
helps.  It may not be the very latest version, I keep messing with it:

#include <u.h>
#include <libc.h>

static char *awday[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
static char *wday[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
			"Friday", "Saturday"};
static char *amon[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
			    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
static char *mon[12] = {"January", "February", "March", "April", "May", "June",
		"July", "August", "September", "October", "November", "December"};
static char *ampm[2] = {"AM", "PM"};
static char *tz[2] = {"EST", "EDT"};

static int jan1(int);
static char *strval(char *, char *, char **, int, int);
static char *dval(char *, char *, int, int);

long
strftime (char *s, long maxsize, const char *format, const Tm *t)
{
	char *sp, *se, *fp;
	int i;

	sp = s;
	se = s+maxsize;
	for(fp=(char *)format; *fp && sp<se; fp++){
		if(*fp != '%')
			*sp++ = *fp;
		else switch(*++fp){
			case 'a':
				sp = strval(sp, se, awday, t->wday, 7);
				break;
			case 'A':
				sp = strval(sp, se, wday, t->wday, 7);
				break;
			case 'b':
				sp = strval(sp, se, amon, t->mon, 12);
				break;
			case 'B':
				sp = strval(sp, se, mon, t->mon, 12);
				break;
			case 'c':
				sp += strftime(sp, se-sp, "%a %b %d %H:%M:%S %Y", t);
				break;
			case 'd':
				sp = dval(sp, se, t->mday, 2);
				break;
			case 'H':
				sp = dval(sp, se, t->hour, 2);
				break;
			case 'I':
				i = t->hour;
				if(i == 0)
					i = 12;
				else if(i > 12)
					i -= 12;
				sp = dval(sp, se, i, 2);
				break;
			case 'j':
				sp = dval(sp, se, t->yday+1, 3);
				break;
			case 'm':
				sp = dval(sp, se, t->mon+1, 2);
				break;
			case 'M':
				sp = dval(sp, se, t->min, 2);
				break;
			case 'p':
				i = (t->hour < 12)? 0 : 1;
				sp = strval(sp, se, ampm, i, 2);
				break;
			case 'S':
				sp = dval(sp, se, t->sec, 2);
				break;
			case 'U':
				i = 7-jan1(t->year);
				if(i == 7)
					i = 0;
				/* Now i is yday number of first sunday in year */
				if(t->yday < i)
					i = 0;
				else
					i = (t->yday-i)/7 + 1;
				sp = dval(sp, se, i, 2);
				break;
			case 'w':
				sp = dval(sp, se, t->wday, 1);
				break;
			case 'W':
				i = 8-jan1(t->year);
				if(i >= 7)
					i -= 7;
				/* Now i is yday number of first monday in year */
				if(t->yday < i)
					i = 0;
				else
					i = (t->yday-i)/7 + 1;
				sp = dval(sp, se, i, 2);
				break;
			case 'x':
				sp += strftime(sp, se-sp, "%a %b %d, %Y", t);
				break;
			case 'X':
				sp += strftime(sp, se-sp, "%H:%M:%S", t);
				break;
			case 'y':
				sp = dval(sp, se, t->year%100, 2);
				break;
			case 'Y':
				sp = dval(sp, se, t->year+1900, 4);
				break;
			case 'Z':
				/* hack for now: assume eastern time zone */
				i = /* t->isdst? 1 : */ 0;
				sp = strval(sp, se, tz, i, 2);
				break;
			case 0:
				fp--; /* stop loop after next fp incr */
				break;
			default:
				*sp++ = *fp;
			}
	}
	if(*fp)
		sp = s; /* format string didn't end: no room for conversion */
	if(sp<se)
		*sp = 0;
	return sp-s;
}

static char *
strval(char *start, char *end, char **array, int index, int alen)
{
	int n;

	if(index<0 || index>=alen){
		*start = '?';
		return start+1;
	}
	n = strlen(array[index]);
	if(n > end-start)
		n = end-start;
	memcpy(start, array[index], n);
	return start+n;
}

static char *
dval(char *start, char *end, int val, int width)
{
	char *p;

	if(val<0 || end-start<width){
		*start = '?';
		return start+1;
	}
	p = start+width-1;
	while(p>=start){
		*p-- = val%10 + '0';
		val /= 10;
	}
	if(val>0)
		*start = '*';
	return start+width;
}

/*
 *	return day of the week
 *	of jan 1 of given year
 */
static int
jan1(int yr)
{
	int y, d;

/*
 *	normal gregorian calendar
 *	one extra day per four years
 */

	y = yr+1900;
	d = 4+y+(y+3)/4;

/*
 *	julian calendar
 *	regular gregorian
 *	less three days per 400
 */

	if(y > 1800) {
		d -= (y-1701)/100;
		d += (y-1601)/400;
	}

/*
 *	great calendar changeover instant
 */

	if(y > 1752)
		d += 3;

	return(d%7);
}




  reply	other threads:[~2014-09-02  8:27 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-02  7:07 Steve Simon
2014-09-02  8:27 ` lucio [this message]
2014-09-02  8:46 ` arnold
2014-09-02  9:40   ` Jens Staal
2014-09-02 14:07     ` arnold
2014-09-02 14:22   ` Steve Simon
2014-09-02 14:29     ` arnold
2014-09-02 17:02 ` erik quanstrom
2014-09-02 18:18   ` Steve Simon
2014-09-02 19:10     ` erik quanstrom
2014-09-02 20:04       ` Bakul Shah
2014-09-02 21:05         ` erik quanstrom
2014-09-02 21:50           ` Kurt H Maier
2014-09-02 23:00             ` erik quanstrom
2014-09-02 23:04               ` Bakul Shah
2014-09-02 23:19                 ` erik quanstrom
2014-09-02 23:29                   ` Bakul Shah
2014-09-02 21:10         ` Skip Tavakkolian
2014-09-02 21:14           ` Steve Simon
2014-09-02 21:27           ` Bakul Shah
2014-09-02 21:43             ` Skip Tavakkolian
2014-09-02 18:36 ` Kurt H Maier
2014-09-02 19:18   ` Steve Simon
2014-09-02 23:34 sl

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1b89f632938db085db4f9b3fa706bc5e@proxima.alt.za \
    --to=lucio@proxima.alt.za \
    --cc=9fans@9fans.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).