本着共享的精神,封装好的API放在github上,不是每一个function我都测试过,我自己需要用的那几个API是没有问题的。 :)
代码地址: https://github.com/yongzhy/t32
自己用golang写了一个短代码用来计算两个日期间隔,间隔用X年X月X日表示出来,比如2010-07-19到2012-09-18的间隔就是2年1月30天。写这个程序是用来具体算小孩的年龄,闰年也有考虑在内,比如 2010-07-19到2012-03-18是1年7个月28天,因为2012年2月有29天。
package main
import (
"flag"
"fmt"
"os"
"strconv"
"strings"
"time"
)
type DateDiff struct {
years, months, days int
}
var DAYS = map[time.Month]int{
time.January: 31,
time.February: 28,
time.March: 31,
time.April: 30,
time.May: 31,
time.June: 30,
time.July: 31,
time.August: 31,
time.September: 30,
time.October: 31,
time.November: 30,
time.December: 31,
}
func LeapYear(year int) bool {
ret := false
if year%4 == 0 {
if year%100 != 0 {
ret = true
} else if year%400 == 0 {
ret = true
}
}
return ret
}
// passed in strings hould be in either of the following two format:
// yyyy-mm-dd
// yyyy/mm/dd
func ParseDate(s string) time.Time {
var it []string
if strings.Index(s, "-") > 0 {
it = strings.Split(s, "-")
} else if strings.Index(s, "/") > 0 {
it = strings.Split(s, "/")
} else {
fmt.Printf("Error: wrong date format\n")
flag.Usage()
os.Exit(-1)
}
y, err := strconv.ParseInt(it[0], 10, 64)
if err != nil {
panic(err)
}
m, err := strconv.ParseInt(it[1], 10, 64)
if err != nil {
panic(err)
}
d, err := strconv.ParseInt(it[2], 10, 64)
if err != nil {
panic(err)
}
return time.Date(int(y), time.Month(int(m)), int(d), 0, 0, 0, 0, time.UTC)
}
func main() {
var ds, de string
flag.StringVar(&ds, "start", "", "[*]Start Date in format of yyyy/mm/dd or yyyy-mm-dd")
flag.StringVar(&de, "end", "today", "End Date in format of yyyy/mm/dd or yyyy-mm-dd")
flag.Parse()
if ds == "" {
fmt.Printf("Error: No start date is specified\n")
flag.Usage()
os.Exit(-1)
}
var start, end time.Time
start = ParseDate(ds)
if de == "today" {
end = time.Now()
} else {
end = ParseDate(de)
}
var diff DateDiff
var borrowed bool = false
var daysBorrowed int = 0
// Days difference
if end.Day() >= start.Day() {
diff.days = end.Day() - start.Day()
} else {
daysBorrowed = DAYS[end.Month()-1]
if LeapYear(end.Year()) && end.Month() == time.March {
daysBorrowed++ // February in leap year is 29 days
}
diff.days = end.Day() + daysBorrowed - start.Day()
borrowed = true
}
// Month Difference
endMonth := end.Month()
if borrowed == true {
if endMonth == time.January {
endMonth = time.December
} else {
endMonth--
}
borrowed = false
}
if endMonth >= start.Month() {
diff.months = int(endMonth) - int(start.Month())
} else {
diff.months = int(endMonth) + 12 - int(start.Month())
borrowed = true
}
// Year difference
if borrowed {
diff.years = end.Year() - 1 - start.Year()
} else {
diff.years = end.Year() - start.Year()
}
// Output
if diff.years < 0 || diff.months < 0 || diff.days < 0 {
fmt.Printf("Error: end date should after start date\n")
} else {
fmt.Printf("Difference of %d Years %d Months %d Days\n", diff.years, diff.months, diff.days)
}
}
前一段时间用go写了一个查看perforce的history的小程序,go没有什么成熟的ui包,所以我选用web界面,程序本身做两件事情,一个后台更新perforce的history到本地的sqlite数据库,另外一个后台当作web服务器,处理client的request,生成json数据。
在写这个程序的时候,发现要生成json数据的结构里field名字首字母要大写。因为是一个自己用的小程序,也没有去深究到底可不可以生成首字母是小写的json数据。今天逛stackoverflow的时候看到有人问这个问题,看了看,原来go的json包有解决办法,只是自己看文档的时候没有怎么注意罢了。要加tag来做这件事情。
下面这段示例代码就的output:
{"field_a":1234,"field_b":"hello"}
package main
import "fmt"
import "encoding/json"
func main() {
type Test struct {
A int `json:"field_a"`
B string `json:"field_b"`
}
A := Test{1234, "hello"}
b, _ := json.Marshal(A)
fmt.Println(string(b))
}
今天终于在github上有了一个真正的自己的项目,虽然是一个很简单,很小的项目,不过还是值得纪念一下。
项目地址: https://github.com/yongzhy/goploticus
这个是libploticus的Go语言封装。
A free, GPL, non-interactive software package for producing plots, charts, and graphics from data. It was developed in a Unix/C environment and runs onvarious Unix, Linux, and win32 systems. ploticus is good for automated or just-in-time graph generation, handles date and time data nicely, and has basic statistical capabilities. It allows significant user control over colors, styles, options and details. Ploticus is a mature package, available since 1999, and version 2.40 has more than 12,000 downloads to date. Ploticus was discussed in this 2008 review on Linux.com.
因为是第一次封装C的API,折腾了一阵子才发现要让cgo编译代码,import “C” 必须是单独一行.
可以编辑的代码:
//#cgo LDFLAGS: -lploticus
//#include <libploticus.h>
//#include <stdlib.h>
import "C"
不可以被编辑的代码:
//#cgo LDFLAGS: -lploticus
//#include <libploticus.h>
//#include <stdlib.h>
import (
"C"
)
什么东西,都要试了才真正知道。