关于JavaScript中判断滚动条到底部的说明

判断滚动条到底部,需要用到DOM的三个属性值,即scrollTop(滚动条在Y轴上的滚动距离)、clientHeight(内容可视区域的高度)、scrollHeight(容可视区域的高度加上溢出滚动的距离)。从这个三个属性可以看出来,滚动条到底部的条件即为:

scrollTop + clientHeight == scrollHeight

一、使用标准DOM方法:

// 定义滚动条判断方法
(function (window, undefined) {
    if (typeof (window.getScrollTop) != "function") {
        // 获取滚动条在Y轴上的滚动距离  
        window.getScrollTop = function () {
            var scrollTop = 0, bodyScrollTop = 0, documentScrollTop = 0;
            if (document.body) {
                bodyScrollTop = document.body.scrollTop;
            }
            if (document.documentElement) {
                documentScrollTop = document.documentElement.scrollTop;
            }
            scrollTop = (bodyScrollTop - documentScrollTop > 0) ? bodyScrollTop : documentScrollTop;
            return scrollTop;
        };
    }
    if (typeof (window.getScrollHeight) != "function") {
        // 获取文档的总高度 
        window.getScrollHeight = function () {
            var scrollHeight = 0, bodyScrollHeight = 0, documentScrollHeight = 0;
            if (document.body) {
                bodyScrollHeight = document.body.scrollHeight;
            }
            if (document.documentElement) {
                documentScrollHeight = document.documentElement.scrollHeight;
            }
            scrollHeight = (bodyScrollHeight - documentScrollHeight > 0) ? bodyScrollHeight : documentScrollHeight;
            return scrollHeight;
        };
    }
    if (typeof (window.getWindowHeight) != "function") {
        // 获取浏览器视口的高度 
        window.getWindowHeight = function () {
            var windowHeight = 0;
            if (document.compatMode == "CSS1Compat") {
                windowHeight = document.documentElement.clientHeight;
            } else {
                windowHeight = document.body.clientHeight;
            }
            return windowHeight;
        };
    }
})(window);

// 添加滚动事件
window.onscroll = function () {
    // 判断是否滚动条是否在底部
    if (getScrollTop() + getWindowHeight() == getScrollHeight()) {
        alert("滚动条在底部");
    }
};

二、使用jQuery框架方法:

// 定义jQuery对象
var $window = jQuery(window);
var $document = jQuery(document);
// 添加滚动事件
$window.scroll(function () {
    // 获取滚动条在Y轴上的滚动距离
    var scrollTop = $window.scrollTop();
    // 获取文档的总高度 
    var scrollHeight = $document.height();
    // 获取浏览器视口的高度 
    var windowHeight = $window.height();
    // 判断是否滚动条是否在底部
    if (scrollTop + windowHeight == scrollHeight) {
        alert("滚动条在底部");
    }
});

关于C#中读写Config文件配置数据的说明

在编写C#程序时,我们可以为每个应用程序创建一个默认的配置文件,一般命名为App.config,其在编译后将会生成一个以应用程序名称命名的并且后缀名为config的文件。我们可以将需要的配置信息记录在该文件的configuration/appSettings节点下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="key1" value="value1"/>
    <add key="key2" value="value2"/>
  </appSettings>
</configuration>

该文件实际是一个以configuration为根节点的XML文件,其除了可以用appSettings节点来配置一些常规的数据外,还可以使用其他很多节点来配置应用程序的相关运行数据和环境,如assemblyBinding(程序集绑定)、connectionStrings(连接字符串)等。对该配置文件的读写除了可以采用常规的读写XML文件方法外,我们还可以通过C#中的静态类ConfigurationManager(在System.Configuration.dll中)来管理配置数据。

一、读取配置数据:
使用ConfigurationManager类的AppSettings属性(或者ConnectionStrings属性)来读取配置文件数据:

// 使用key属性读取
string value1 = ConfigurationManager.AppSettings["key1"];
// 使用索引读取
string value2 = ConfigurationManager.AppSettings[1];

二、写入配置数据:
使用ConfigurationManager类的Configuration对象来写入配置文件数据:

// 获取可修改的配置对象
Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
// 获取AppSettings的配置集合
KeyValueConfigurationCollection settings = configuration.AppSettings.Settings;
// 移除配置项
settings.Remove("key1");
settings.Remove("key2");
// 写入配置项
settings.Add("key", "value");
// 保存修改过的配置信息
configuration.Save(ConfigurationSaveMode.Modified);
// 刷新配置节点,使程序在下次检索时重新从磁盘中读取。
ConfigurationManager.RefreshSection("appSettings");

更多信息请参阅:ConfigurationManager 类 (System.Configuration)

关于SQLite中连接字符串的说明

SQLite在SQLite.NET中的连接字符串

基本

Data Source=C:/sqlite.db;Version=3;

SQLite-2版本不支持此方法

使用内存数据库

Data Source=:memory:;Version=3;New=True;

使用UTF-16编码

Data Source=C:/sqlite.db;Version=3;UseUTF16Encoding=True;

使用密码

Data Source=C:/sqlite.db;Version=3;Password=[password];

使用SQLite-3.3x版本之前的数据库格式

Data Source=C:/sqlite.db;Version=3;Legacy Format=True;

使用连接池

Data Source=C:/sqlite.db;Version=3;Pooling=True;Max Pool Size=100;

使用只读连接

Data Source=C:/sqlite.db;Version=3;Read Only=True;

将DateTime.Ticks作为datetime格式

Data Source=C:/sqlite.db;Version=3;DateTimeFormat=Ticks;

默认使用ISO8601日期时间格式

将GUID作为text格式

Data Source=C:/sqlite.db;Version=3;BinaryGUID=False;

存储GUID文本将使用更多的数据库空间。

指定缓存大小

Data Source=C:/sqlite.db;Version=3;Cache Size=2000;

以字节为单位

指定数据页大小

Data Source=C:/sqlite.db;Version=3;Page Size=1024;

以字节为单位

禁止在分布式事务中记录

Data Source=C:/sqlite.db;Version=3;Enlist=N;

禁止创建数据库

Data Source=C:/sqlite.db;Version=3;FailIfMissing=True;

限制数据库大小

Data Source=C:/sqlite.db;Version=3;Max Page Count=5000;

禁用日志文件

Data Source=C:/sqlite.db;Version=3;Journal Mode=Off;

使用日志文件

Data Source=C:/sqlite.db;Version=3;Journal Mode=Persist;

控制文件刷新

Data Source=C:/sqlite.db;Version=3;Synchronous=Full;

设置FULL后每次操作后自动刷新,否则由操作系统决定何时去刷新

SQLite在ADO.NET驱动中的连接字符串

标准

Data Source=C:/sqlite.db;Version=3;

对于SQLite-2.x版本使用Version=2,对于SQLite-3.x版本使用Version=3

创建新数据库

Data Source=C:/sqlite.db;Version=3;New=True;

使用数据库压缩

Data Source=C:/sqlite.db;Version=3;Compress=True;

指定缓存大小

Data Source=C:/sqlite.db;Version=3;Cache Size=3000;

使用UTF-8编码

Data Source=C:/sqlite.db;Version=3;UTF8Encoding=True;

使用UTF-16编码

Data Source=C:/sqlite.db;Version=3;UTF16Encoding=True;

SQLite在ODBC驱动中的连接字符串

标准

DRIVER=SQLite3 ODBC Driver;Database=C:/sqlite.db;LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;

SQLite在.NET Framework的ODBC驱动中的连接字符串

使用ODBC驱动

Driver=[驱动名称];OdbcKey1=[Value1];OdbcKey2=[Value2];

更多信息请参阅:SQLite connection strings – ConnectionStrings.com

关于JavaScript中实现form和iframe异步文件上传的说明

在Web编程中,我们常常需要使用文件的上传功能。默认的普通文件上传功能是随form表单提交时执行上传的,表单提交的进程将伴随着文件上传进程。当需要上传的文件太大时,表单提交的时间将会大大增加,但是在表单提交期间我们又无法进行其他操作,因此异步文件上传就变成了Web编程中经常需要解决的问题。
下面介绍如何使用form结合ifame的方式实现简单的异步文件上传功能,其中关于HTML元素的操作使用了jQuery框架,当然有需要的也可以将这部分代码改写成标准DOM方式实现:

一、定义异步文件上传方法:

// 定义异步文件上传构造器
(function (window, jQuery, undefined) {
    // 判断异步文件上传构造器是否已经定义
    if (typeof (window.asyncUpload) == "function") {
        return;
    }
    /**
    * options:异步文件上传数据参数设置
    */
    window.asyncUpload = function (options) {
        if (!options) {
            options = {};
        }
        // 构造隐藏的form和iframe
        var name = new Date().getTime();
        var iframeName = "iframe_" + name;
        var formName = "form_" + name;
        var $div = jQuery("<div style='display: none'></div>").appendTo("body");
        var $iframe = jQuery("<iframe name='" + iframeName + "'></iframe>").appendTo($div);
        var $form = jQuery("<form name='" + formName + "' method='post' enctype='multipart/form-data' encoding='multipart/form-data'></form>");
        // 设置form提交到iframe中
        $form.attr("target", iframeName).attr("action", options.url).appendTo($div);
        // 剪切文件上传input到form中,并克隆新的文件上传input到原始位置
        if (options.files) {
            for (var key in options.files) {
                var $file = jQuery(options.files[key]);
                $file.clone(true).insertBefore($file);
                $file.appendTo($form).removeAttr("id");
            }
        }
        // 通过在form中创建隐藏的input来提交其他需要提交的数据
        if (options.params) {
            for (var key in options.params) {
                jQuery("<input type='hidden' name='" + key + "' />").appendTo($form).val(options.params[key]);
            }
        }
        // 绑定iframe的load事件
        $iframe.load(function () {
            // 触发上传完成响应事件
            if (typeof (options.callback) == "function") {
                var iframe = this;
                // 定义上传结果对象
                var data = {
                    responseText: "",
                    responseXML: ""
                };
                // 获取上传结果
                if (iframe.contentWindow) {
                    data.responseText = iframe.contentWindow.document.body ? iframe.contentWindow.document.body.innerHTML : null;
                    data.responseXML = iframe.contentWindow.document.XMLDocument ? iframe.contentWindow.document.XMLDocument : iframe.contentWindow.document;
                } else if (iframe.contentDocument) {
                    data.responseText = iframe.contentDocument.document.body ? iframe.contentDocument.document.body.innerHTML : null;
                    data.responseXML = iframe.contentDocument.document.XMLDocument ? iframe.contentDocument.document.XMLDocument : iframe.contentDocument.document;
                }
                // 根据数据类型构造上传完成响应事件参数
                var args = null;
                var dataType = jQuery.trim(options.dataType);
                if (dataType == "json") {
                    // 将json字符串构造成JavaScript对象
                    eval("args = " + data.responseText + ";");
                    args = [args];
                } else if (dataType == "xml") {
                    args = [data.responseXML];
                } else {
                    args = [data.responseText, data.responseXML];
                }
                // 回调上传完成响应事件
                options.callback.apply(iframe, args);
            }
            // 移除并释放临时数据
            $div.remove();
        });
        // 提交表单
        $form.submit();
    };
})(window, jQuery);

二、参数说明:
该异步文件上传方法需要options对象参数,其中包括:

url:string,必填,上传提交地址

files:array,必填,上传的文件数组,支持DOM对象、jQuery对象、jQuery选择器

params:object,可选,其他需要提交的数据

dataType:string,可选,上传完成后响应的结果数据类型,可选值有xml、json、html,默认为html

callback:function,可选,上传完成后响应事件,事件参数为响应结果,参数类型以options.dataType定义为准

三、调用示例:
定义需要进行文件上传的input元素,该元素可以在HTML文档中body元素下任意位置:

<input id="file" name="file" type="file" />

在JavaScript中调用异步文件上传方法:

// 绑定文件上传input的change事件,使用户选择文件后自动触发上传
jQuery("#file").change(function () {
    // 开始异步文件上传
    asyncUpload({
        // 上传提交地址
        url: "upload.php",
        // 上传的文件数组
        files: [jQuery("#file")],
        // 其他需要提交的数据
        params: {
            text: "file"
        },
        // 上传完成后响应的结果数据类型
        dataType: "html",
        // 上传完成后响应事件
        callback: function (html, xml) {
            alert(html);
        }
    });
});

上传文件提交地址的服务端可以使用基本的获取上传文件方法对上传上来的文件进行操作,最后返回相应的响应数据即可。

关于C#中日期和时间字符串格式化的说明

一、标准日期和时间格式字符串:
标准日期和时间格式字符串使用单个格式说明符来定义日期和时间值的文本表示形式。包含一个以上字符(包括空白)的任何日期和时间格式字符串都会被解释为自定义日期和时间格式字符串。可通过两种方式使用标准或自定义格式字符串:定义由格式设置操作生成的字符串;定义可通过分析操作转换为DateTime或DateTimeOffset值的日期和时间值的文本表示形式。
标准日期和时间格式字符串可以与DateTime和DateTimeOffset值一起使用。
以下列出支持的标准日期和时间格式说明符并显示由每个格式说明符产生的示例输出:

“d”
说明:短日期模式。
示例:
2009-06-15T13:45:30 -> 6/15/2009 (en-US)
2009-06-15T13:45:30 -> 15/06/2009 (fr-FR)
2009-06-15T13:45:30 -> 2009/06/15 (ja-JP)

“D”
说明:长日期模式。
示例:
2009-06-15T13:45:30 -> Monday, June 15, 2009 (en-US)
2009-06-15T13:45:30 -> Montag, 15.Juni 2009 (de-DE)

“f”
说明:完整日期/时间模式(短时间)。
示例:
2009-06-15T13:45:30 -> Monday, June 15, 2009 1:45 PM (en-US)
2009-06-15T13:45:30 -> den 15 juni 2009 13:45 (sv-SE)

“F”
说明:完整日期/时间模式(长时间)。
示例:
2009-06-15T13:45:30 -> Monday, June 15, 2009 1:45:30 PM (zh-CN)
2009-06-15T13:45:30 -> den 15 juni 2009 13:45:30 (sv-SE)

“g”
说明:常规日期/时间模式(短时间)。
示例:
2009-06-15T13:45:30 -> 6/15/2009 1:45 PM (en-US)
2009-06-15T13:45:30 -> 15/06/2009 13:45 (es-ES)
2009-06-15T13:45:30 -> 2009/6/15 13:45 (zh-CN)

“G”
说明:常规日期/时间模式(长时间)。
示例:
2009-06-15T13:45:30 -> 6/15/2009 1:45:30 PM (en-US)
2009-06-15T13:45:30 -> 15/06/2009 13:45:30 (es-ES)
2009-06-15T13:45:30 -> 2009/6/15 13:45:30 (zh-CN)

“M”、”m”
说明:月/日模式。
示例:
2009-06-15T13:45:30 -> June 15 (en-US)
2009-06-15T13:45:30 -> 15.juni (da-DK)
2009-06-15T13:45:30 -> 15 Juni (id-ID)

“O”、”o”
说明:往返日期/时间模式。
示例:
DateTime值:
2009-06-15T13:45:30 (DateTimeKind.Local) -> 2009-06-15T13:45:30.0000000-07:00
2009-06-15T13:45:30 (DateTimeKind.Utc) -> 2009-06-15T13:45:30.0000000Z
2009-06-15T13:45:30 (DateTimeKind.Unspecified) -> 2009-06-15T13:45:30.0000000
DateTimeOffset值:
2009-06-15T13:45:30-07:00 -> 2009-06-15T13:45:30.0000000-07:00

“R”、”r”
说明:RFC1123模式。
示例:
2009-06-15T13:45:30 -> Mon, 15 Jun 2009 20:45:30 GMT

“s”
说明:可排序日期/时间模式。
示例:
2009-06-15T13:45:30 (DateTimeKind.Local) -> 2009-06-15T13:45:30
2009-06-15T13:45:30 (DateTimeKind.Utc) -> 2009-06-15T13:45:30

“t”
说明:短时间模式。
示例:
2009-06-15T13:45:30 -> 1:45 PM (en-US)
2009-06-15T13:45:30 -> 13:45 (hr-HR)

“T”
说明:长时间模式。
示例:
2009-06-15T13:45:30 -> 1:45:30 PM (en-US)
2009-06-15T13:45:30 -> 13:45:30 (hr-HR)

“u”
说明:通用可排序日期/时间模式。
示例:
2009-06-15T13:45:30 -> 2009-06-15 20:45:30Z

“U”
说明:通用完整日期/时间模式。
示例:
2009-06-15T13:45:30 -> Monday, June 15, 2009 8:45:30 PM (en-US)
2009-06-15T13:45:30 -> den 15 juni 2009 20:45:30 (sv-SE)

“Y”、”y”
说明:年月模式。
示例:
2009-06-15T13:45:30 -> June, 2009 (en-US)
2009-06-15T13:45:30 -> juni 2009 (da-DK)
2009-06-15T13:45:30 -> Juni 2009 (id-ID)

任何其他单个字符
说明:未知说明符,引发运行时FormatException。

二、自定义日期和时间格式字符串:
日期和时间格式字符串定义由格式设置操作生成的DateTime或DateTimeOffset值的文本表示形式。它还可定义分析操作中需要的日期和时间值的表示形式,以便成功将字符串转换为日期和时间。自定义格式字符串由一个或多个自定义日期和时间格式说明符组成。任何不是标准日期和时间格式字符串的字符串都会解释为自定义日期和时间格式字符串。
自定义日期和时间格式字符串可以与DateTime和DateTimeOffset值一起使用。
以下列出支持的自定义日期和时间格式说明符并显示由每个格式说明符产生的示例输出:

“d”
说明:一个月中的某一天(1到31)。
示例:
2009-06-01T13:45:30 -> 1
2009-06-15T13:45:30 -> 15

“dd”
说明:一个月中的某一天(01到31)。
示例:
2009-06-01T13:45:30 -> 01
2009-06-15T13:45:30 -> 15

“ddd”
说明:一周中某天的缩写名称。
示例:
2009-06-15T13:45:30 -> Mon (en-US)
2009-06-15T13:45:30 -> lun.(fr-FR)

“dddd”
说明:一周中某天的完整名称。
示例:
2009-06-15T13:45:30 -> Monday (en-US)
2009-06-15T13:45:30 -> lundi (fr-FR)

“f”
说明:日期和时间值的十分之几秒。
示例:
2009-06-15T13:45:30.6170000 -> 6
2009-06-15T13:45:30.05 -> 0

“ff”
说明:日期和时间值的百分之几秒。
示例:
2009-06-15T13:45:30.6170000 -> 61
2009-06-15T13:45:30.0500000 -> 00

“fff”
说明:日期和时间值的千分之几秒。
示例:
6/15/2009 13:45:30.617 -> 617
6/15/2009 13:45:30.0005 -> 000

“ffff”
说明:日期和时间值的万分之几秒。
示例:
2009-06-15T13:45:30.6175000 -> 6175
2009-06-15T13:45:30.0000500 -> 0000

“fffff”
说明:日期和时间值的十万分之几秒。
示例:
2009-06-15T13:45:30.6175400 -> 61754
6/15/2009 13:45:30.000005 -> 00000

“ffffff”
说明:日期和时间值的百万分之几秒。
示例:
2009-06-15T13:45:30.6175420 -> 617542
2009-06-15T13:45:30.0000005 -> 000000

“fffffff”
说明:日期和时间值的千万分之几秒。
示例:
2009-06-15T13:45:30.6175425 -> 6175425
2009-06-15T13:45:30.0001150 -> 0001150

“F”
说明:如果非零,则为日期和时间值的十分之几秒。
示例:
2009-06-15T13:45:30.6170000 -> 6
2009-06-15T13:45:30.0500000 ->(无输出)

“FF”
说明:如果非零,则为日期和时间值的百分之几秒。
示例:
2009-06-15T13:45:30.6170000 -> 61
2009-06-15T13:45:30.0050000 ->(无输出)

“FFF”
说明:如果非零,则为日期和时间值的千分之几秒。
示例:
2009-06-15T13:45:30.6170000 -> 617
2009-06-15T13:45:30.0005000 ->(无输出)

“FFFF”
说明:如果非零,则为日期和时间值的万分之几秒。
示例:
2009-06-15T13:45:30.5275000 -> 5275
2009-06-15T13:45:30.0000500 ->(无输出)

“FFFFF”
说明:如果非零,则为日期和时间值的十万分之几秒。
示例:
2009-06-15T13:45:30.6175400 -> 61754
2009-06-15T13:45:30.0000050 ->(无输出)

“FFFFFF”
说明:如果非零,则为日期和时间值的百万分之几秒。
示例:
2009-06-15T13:45:30.6175420 -> 617542
2009-06-15T13:45:30.0000005 ->(无输出)

“FFFFFFF”
说明:如果非零,则为日期和时间值的千万分之几秒。
示例:
2009-06-15T13:45:30.6175425 -> 6175425
2009-06-15T13:45:30.0001150 -> 000115

“g”、”gg”
说明:时期或纪元。
示例:
2009-06-15T13:45:30.6170000 -> A.D.

“h”
说明:采用12小时制的小时(从1到12)。
示例:
2009-06-15T01:45:30 -> 1
2009-06-15T13:45:30 -> 1

“hh”
说明:说明:采用12小时制的小时(从01到12)。
示例:
2009-06-15T01:45:30 -> 01
2009-06-15T13:45:30 -> 01

“H”
说明:采用24小时制的小时(从0到23)。
示例:
2009-06-15T01:45:30 -> 1
2009-06-15T13:45:30 -> 13

“HH”
说明:采用24小时制的小时(从00到23)。
示例:
2009-06-15T01:45:30 -> 01
2009-06-15T13:45:30 -> 13

“K”
说明:时区信息。
示例:
DateTime值:
2009-06-15T13:45:30, Kind Unspecified ->
2009-06-15T13:45:30, Kind Utc -> Z
2009-06-15T13:45:30, Kind Local -> -07:00(取决于本地计算机的设置)
DateTimeOffset值:
2009-06-15T01:45:30-07:00 -> -07:00
2009-06-15T08:45:30+00:00 -> +00:00

“m”
说明:分钟(0到59)。
示例:
2009-06-15T01:09:30 -> 9
2009-06-15T13:29:30 -> 29

“mm”
说明:分钟(00到59)。
示例:
2009-06-15T01:09:30 -> 09
2009-06-15T01:45:30 -> 45

“M”
说明:月份(1到12)。
示例:
2009-06-15T13:45:30 -> 6

“MM”
说明:月份(1到12)。
示例:
2009-06-15T13:45:30 -> 06

“MMM”
说明:月份的缩写名称。
示例:
2009-06-15T13:45:30 -> Jun (en-US)
2009-06-15T13:45:30 -> juin (fr-FR)
2009-06-15T13:45:30 -> Jun (zu-ZA)

“MMMM”
说明:月份的完整名称。
示例:
2009-06-15T13:45:30 -> June (en-US)
2009-06-15T13:45:30 -> juni (da-DK)
2009-06-15T13:45:30 -> uJuni (zu-ZA)

“s”
说明:秒(0到59)。
示例:
2009-06-15T13:45:09 -> 9

“ss”
说明:秒(00到59)。
示例:
2009-06-15T13:45:09 -> 09

“t”
说明:AM/PM指示符的第一个字符。
示例:
2009-06-15T13:45:30 -> P (en-US)
2009-06-15T13:45:30 -> (fr-FR)

“tt”
说明:AM/PM指示符。
示例:
2009-06-15T13:45:30 -> PM (en-US)
2009-06-15T13:45:30 -> (fr-FR)

“y”
说明:年份(0到99)。
示例:
0001-01-01T00:00:00 -> 1
0900-01-01T00:00:00 -> 0
1900-01-01T00:00:00 -> 0
2009-06-15T13:45:30 -> 9
2019-06-15T13:45:30 -> 19

“yy”
说明:年份(00到99)。
示例:
0001-01-01T00:00:00 -> 01
0900-01-01T00:00:00 -> 00
1900-01-01T00:00:00 -> 00
2019-06-15T13:45:30 -> 19

“yyy”
说明:年份(最少三位数字)。
示例:
0001-01-01T00:00:00 -> 001
0900-01-01T00:00:00 -> 900
1900-01-01T00:00:00 -> 1900
2009-06-15T13:45:30 -> 2009

“yyyy”
说明:由四位数字表示的年份。
示例:
0001-01-01T00:00:00 -> 0001
0900-01-01T00:00:00 -> 0900
1900-01-01T00:00:00 -> 1900
2009-06-15T13:45:30 -> 2009

“yyyyy”
说明:由五位数字表示的年份。
示例:
0001-01-01T00:00:00 -> 00001
2009-06-15T13:45:30 -> 02009

“z”
说明:相对于UTC的小时偏移量,无前导零。
示例:
2009-06-15T13:45:30-07:00 -> -7

“zz”
说明:相对于UTC的小时偏移量,带有表示一位数值的前导零。
示例:
2009-06-15T13:45:30-07:00 -> -07

“zzz”
说明:相对于UTC的小时和分钟偏移量。
示例:
2009-06-15T13:45:30-07:00 -> -07:00

“:”
说明:时间分隔符。
示例:
2009-06-15T13:45:30 -> : (en-US)
2009-06-15T13:45:30 -> .(it-IT)
2009-06-15T13:45:30 -> : (ja-JP)

“/”
说明:日期分隔符。
示例:
2009-06-15T13:45:30 -> / (en-US)
2009-06-15T13:45:30 -> – (ar-DZ)
2009-06-15T13:45:30 -> .(tr-TR)

‘字符’或”字符串”
说明:文本字符串分隔符。
2009-06-15T13:45:30 (“arr:” h:m t) -> arr: 1:45 P
2009-06-15T13:45:30 (‘arr:’ h:m t) -> arr: 1:45 P

“%”
说明:将下面的字符定义为自定义格式说明符。
示例:
2009-06-15T13:45:30 (%h) -> 1

“\”
说明:转义字符。
示例:
2009-06-15T13:45:30 (h \h) -> 1 h

任何其他字符
说明:字符将复制到未更改的结果字符串。
示例:
2009-06-15T01:45:30 (arr hh:mm t) -> arr 01:45 A

更多信息请参阅:标准日期和时间格式字符串自定义日期和时间格式字符串