Miki Tebeka avatar Miki Tebeka committed 28b7357

Working

Comments (0)

Files changed (2)

+/*
+Implementation of Python's strftime in Go
+
+Example:
+	str, err := strftime.Format("%Y/%m/%d", time.Now()) // 2012/12/07
+
+Directives:
+	%a - Locale’s abbreviated weekday name
+	%A - Locale’s full weekday name
+	%b - Locale’s abbreviated month name
+	%B - Locale’s full month name
+	%c - Locale’s appropriate date and time representation
+	%d - Day of the month as a decimal number [01,31]
+	%H - Hour (24-hour clock) as a decimal number [00,23]
+	%I - Hour (12-hour clock) as a decimal number [01,12]
+	%m - Month as a decimal number [01,12]
+	%M - Minute as a decimal number [00,59]
+	%p - Locale’s equivalent of either AM or PM
+	%S - Second as a decimal number [00,61]
+	%x - Locale’s appropriate date representation
+	%X - Locale’s appropriate time representation
+	%y - Year without century as a decimal number [00,99]
+	%Y - Year with century as a decimal number
+	%Z - Time zone name (no characters if no time zone exists)
+
+
+Missing directives:
+	%j - Day of year	
+	%U - Week number of the year
+	%w - Weekday as a decimal number
+	%W - Week number of the year
+*/
 package strftime
 
 import (
+	"fmt"
 	"regexp"
 	"time"
 )
 
-var conv = map[string]string {
-	"%a": "Mon",
-	"%A": "Monday",
+// See http://docs.python.org/2/library/time.html#time.strftime
+var conv = map[string]string{
+	"%a": "Mon",         // Locale’s abbreviated weekday name
+	"%A": "Monday",      // Locale’s full weekday name
+	"%b": "Jan",         // Locale’s abbreviated month name
+	"%B": "January",     // Locale’s full month name
+	"%c": time.RFC1123,  // Locale’s appropriate date and time representation
+	"%d": "02",          // Day of the month as a decimal number [01,31]
+	"%H": "15",          // Hour (24-hour clock) as a decimal number [00,23]
+	"%I": "3",           // Hour (12-hour clock) as a decimal number [01,12]
+	"%m": "01",          // Month as a decimal number [01,12]
+	"%M": "04",          // Minute as a decimal number [00,59]
+	"%p": "PM",          // Locale’s equivalent of either AM or PM
+	"%S": "05",          // Second as a decimal number [00,61]
+	"%x": "01/02/2006",  // Locale’s appropriate date representation
+	"%X": "15:04:05 PM", // Locale’s appropriate time representation
+	"%y": "06",          // Year without century as a decimal number [00,99]
+	"%Y": "2006",        // Year with century as a decimal number
+	"%Z": "MST",         // Time zone name (no characters if no time zone exists)
 }
 
-var r *regexp.Regexp
+var fmtRe *regexp.Regexp
 
 func init() {
-	r = regexp.MustCompile("%[%a-zA-Z]")
+	fmtRe = regexp.MustCompile("%[%a-zA-Z]")
 }
 
+// repl replaces % directives with right time, will panic on unknown directive
 func repl(match string, t time.Time) string {
 	if match == "%%" {
 		return "%"
 
 	format, ok := conv[match]
 	if !ok {
-		return "??"
+		panic(fmt.Errorf("unknown directive - %s", match))
 	}
 	return t.Format(format)
 }
 
-func strftime(format string, t time.Time) string {
-	f := func(match string) string {
+// Format return strings with % directives are expand
+func Format(format string, t time.Time) (result string, err error) {
+	defer func() {
+		if e := recover(); e != nil {
+			result = ""
+			err = e.(error)
+		}
+	}()
+
+	fn := func(match string) string {
 		return repl(match, t)
 	}
-	return r.ReplaceAllStringFunc(format, f)
+	return fmtRe.ReplaceAllStringFunc(format, fn), nil
 }
 var testTime = time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
 
 func TestBasic(t *testing.T) {
-	s := strftime("%a", testTime)
+	s, err := Format("%a", testTime)
+	if err != nil {
+		t.Fatalf("go error - %s", err)
+	}
 	if s != "Tue" {
 		t.Fatalf("Bad day for %s, got %s - expected Tue", testTime, s)
 	}
+
 }
+
+func TestUnknown(t *testing.T) {
+	_, err := Format("%g", testTime)
+	if err == nil {
+		t.Fatalf("managed to expand %g")
+	}
+}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.