src/org/nutz/lang/Times.java
public static long ams(String ds, TimeZone tz) {
        Matcher m = _P_TIME.matcher(ds);
        if (m.find()) {
            int yy = _int(m, 2, 1970);
            int MM = _int(m, 4, 1);
            int dd = _int(m, 6, 1);

            int HH = _int(m, 9, 0);
            int mm = _int(m, 11, 0);
            int ss = _int(m, 14, 0);

            int ms = _int(m, 17, 0);

            /*
             * zozoh: 先干掉，还是用 SimpleDateFormat 吧，"1980-05-01 15:17:23" 之前的日子
             * 得出的时间竟然总是多 30 分钟 long day = (long) D1970(yy, MM, dd); long MS =
             * day * 86400000L; MS += (((long) HH) * 3600L + ((long) mm) * 60L +
             * ss) * 1000L; MS += (long) ms;
             * 
             * // 如果没有指定时区 ... if (null == tz) { // 那么用字符串中带有的时区信息， if
             * (!Strings.isBlank(m.group(17))) { tz =
             * TimeZone.getTimeZone(String.format("GMT%s%s:00", m.group(18),
             * m.group(19))); // tzOffset = Long.parseLong(m.group(19)) // *
             * 3600000L // * (m.group(18).charAt(0) == '-' ? -1 : 1);
             * 
             * } // 如果依然木有，则用系统默认时区 else { tz = TimeZone.getDefault(); } }
             * 
             * // 计算 return MS - tz.getRawOffset() - tz.getDSTSavings();
             */
            String str = String.format("%04d-%02d-%02d %02d:%02d:%02d.%03d",
                                       yy,
                                       MM,
                                       dd,
                                       HH,
                                       mm,
                                       ss,
                                       ms);
            SimpleDateFormat df = (SimpleDateFormat) DF_DATE_TIME_MS4.clone();
            // 那么用字符串中带有的时区信息 ...
            if (null == tz && !Strings.isBlank(m.group(18))) {
                tz = TimeZone.getTimeZone(String.format("GMT%s%s:00", m.group(19), m.group(20)));
            }
            // 指定时区 ...
            if (null != tz)
                df.setTimeZone(tz);
            // 解析返回
            try {
                return df.parse(str).getTime();
            }
            catch (ParseException e) {
                throw Lang.wrapThrow(e);
            }
        } else if (_P_TIME_LONG.matcher(ds).find()) {
            if (ds.endsWith("L"))
                ds.substring(0, ds.length() - 1);
            return Long.parseLong(ds);
        }
        throw Lang.makeThrow("Unexpect date format '%s'", ds);
    }
public static long ams(String ds, TimeZone tz) {
        Matcher m = _P_TIME.matcher(ds);
        if (m.find()) {
            int yy = _int(m, 2, 1970);
            int MM = _int(m, 4, 1);
            int dd = _int(m, 6, 1);

            int HH = _int(m, 9, 0);
            int mm = _int(m, 11, 0);
            int ss = _int(m, 14, 0);

            int ms = _int(m, 17, 0);

            /*
             * zozoh: 先干掉，还是用 SimpleDateFormat 吧，"1980-05-01 15:17:23" 之前的日子
             * 得出的时间竟然总是多 30 分钟 long day = (long) D1970(yy, MM, dd); long MS =
             * day * 86400000L; MS += (((long) HH) * 3600L + ((long) mm) * 60L +
             * ss) * 1000L; MS += (long) ms;
             * 
             * // 如果没有指定时区 ... if (null == tz) { // 那么用字符串中带有的时区信息， if
             * (!Strings.isBlank(m.group(17))) { tz =
             * TimeZone.getTimeZone(String.format("GMT%s%s:00", m.group(18),
             * m.group(19))); // tzOffset = Long.parseLong(m.group(19)) // *
             * 3600000L // * (m.group(18).charAt(0) == '-' ? -1 : 1);
             * 
             * } // 如果依然木有，则用系统默认时区 else { tz = TimeZone.getDefault(); } }
             * 
             * // 计算 return MS - tz.getRawOffset() - tz.getDSTSavings();
             */
            String str = String.format("%04d-%02d-%02d %02d:%02d:%02d.%03d",
                                       yy,
                                       MM,
                                       dd,
                                       HH,
                                       mm,
                                       ss,
                                       ms);
            SimpleDateFormat df = (SimpleDateFormat) DF_DATE_TIME_MS4.clone();
            // 那么用字符串中带有的时区信息 ...
            if (null == tz && !Strings.isBlank(m.group(18))) {
                tz = TimeZone.getTimeZone(String.format("GMT%s%s:00", m.group(19), m.group(20)));
            }
            // 指定时区 ...
            if (null != tz)
                df.setTimeZone(tz);
            // 解析返回
            try {
                return df.parse(str).getTime();
            }
            catch (ParseException e) {
                throw Lang.wrapThrow(e);
            }
        } else if (_P_TIME_LONG.matcher(ds).find()) {
            if (ds.endsWith("L"))
                ds.substring(0, ds.length() - 1);
            return Long.parseLong(ds);
        }
        throw Lang.makeThrow("Unexpect date format '%s'", ds);
    }
根据字符串得到相对于 "UTC 1970-01-01 00:00:00" 的绝对毫秒数。
本函数假想给定的时间字符串是本地时间。所以计算出来结果后，还需要减去时差

支持的时间格式字符串为:

<pre>
yyyy-MM-dd HH:mm:ss
yyyy-MM-dd HH:mm:ss.SSS
yy-MM-dd HH:mm:ss;
yy-MM-dd HH:mm:ss.SSS;
yyyy-MM-dd;
yy-MM-dd;
HH:mm:ss;
HH:mm:ss.SSS;
</pre>

时间字符串后面可以跟 +8 或者 +8:00 表示 GMT+8:00 时区。 同理 -9 或者 -9:00 表示 GMT-9:00 时区

@param ds
时间字符串
@param tz
你给定的时间字符串是属于哪个时区的
@return 时间
@see #_P_TIME