C# 实现的Javascript加密算法

不打算公开的,不过转念一想,反正又没人看,就发出来吧。
这是使用C#来实现的JS加密的,被加密的JS文件,代码需要写的规范,不能少了分号(;)等js中可能会被忽略的符号。
下面是完整代码,自己看吧

    public class JavascriptEncoder
    {
        public static string ENCODE_BASE64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$";
        public bool isDebug = false;

        public string JsEncode(string filename, int offset)
        {
            string js = WebTools.FileObj.ReadFile(HttpContext.Current.Request.MapPath(string.Format("/tmp/{0}", filename)));
            int length = js.Length;

            js = RemoveAnnotation(js);

            WebTools.FileObj.WriteFile(System.Web.HttpContext.Current.Request.MapPath("tmp.js"), js);

            StringBuilder sb = new StringBuilder(js);
           
            sb.Replace(@"\r", " "); //\n替换为空格
            sb.Replace(@"\n", " "); //\n替换为空格
            sb.Replace(Environment.NewLine, " ");
            sb.Replace((char)13, (char)32);
            sb.Replace((char)10, (char)32);
            sb.Replace(@"\", @"\\");    //\替换为\\
            sb.Replace(@"'", @"\'");    // '替换为\'
            js = sb.ToString();
            Regex regex = new Regex(@"([\w\$]+)");            
            MatchCollection matches = regex.Matches(js);
            string element = "";
            List<string> dict = new List<string>();
            int index = 0;
            StringBuilder encscript = new StringBuilder(js);
            StringBuilder dicttab = new StringBuilder();

            foreach (Match match in matches)
            {
                element = match.Groups[1].Value;
                index = dict.FindIndex(m => m.Equals(element));
                if ( index < 0)
                {
                    dict.Add(element);
                    index = dict.Count - 1;
                }
                encscript.Replace(element, Base64Encode(offset + index + 1));
                //regex.Replace(js,element, Base64Encode(offset + index + 1));
            }

            foreach(string d in dict)
            {
                dicttab.AppendFormat("{0}|", d);
            }

            string dictstr = dicttab.ToString().TrimEnd('|');   //字典字符串,删除最后一个|

            string res = formatCode(encscript.ToString(), dictstr, dict.Count, offset);

            return res;
        }

        /// <summary>
        /// 仿Base64
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        private string Base64Encode(int c)
        { 
            string res="";
            if (c < 0) throw new Exception("Error:Offset必须>=0.");
            if (c > 63)
                res = Base64Encode(c >> 6) + Base64Encode(c & 63);
            else {
                //为了配合appendReplacement方法的使用,将$替换为\$
                res = c.Equals(63) ? @"\$" : ENCODE_BASE64[c].ToString();
            }
            return res;
        }

        private string formatCode(string enc, string dict, int size, int offset)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("/* Power by Shoresoft.Cn */\neval(function(E,I,A,D,J,K,L,H){function C(A){return A<62?String.fromCharCode(A+=A<26?65:A<52?71:-4):A<63?'_':A<64?'$':C(A>>6)+C(A&63)}while(A>0)K[C(D--)]=I[--A];function N(A){return K[A]==L[A]?A:K[A]}if(''.replace(/^/,String)){var M=E.match(J),B=M[0],F=E.split(J),G=0;if(E.indexOf(F[0]))F=[''].concat(F);do{H[A++]=F[G++];H[A++]=N(B)}while(B=M[G]);H[A++]=F[G]||'';return H.join('')}return E.replace(J,N)}(");
            sb.Append("'" + enc + "',");
            sb.Append("'" + dict + "'.split('|'),");
            sb.Append(size + "," + (size + offset) + ",/[\\w\\$]+/g, {}, {}, []))");
            return sb.ToString();
        }

        /// <summary>
        /// 移除块注释
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private string RemoveAnnotation(string str)
        {
            string result = str;
            int start = 0;
            int end = 0;
            start = str.IndexOf("/*");
            end = str.IndexOf("*/");
            StringBuilder sb = new StringBuilder(str);
            if (start >= 0 && end>start)
            {
                sb.Remove(start, end - start + 2);
                return RemoveAnnotation(sb.ToString());
            }
            else
                return sb.ToString();
        }
    }

plupload多文件上传插件上传文件出现blob的问题处理

第一次使用plupload,上传文件后发现出现了一个blob文件,同时有的文件并没有被上传上,这是什么鬼,大概的搜了下,有遇到这个问题的,不过没有几个实质性的解决了的这个问题还是得靠自己了。

观察了下plupload的参数,有一项引起了我的怀疑,那就是chunk_size : '1mb',这项设置是什么鬼?查了下,chunk_size 用来设置块的大小,也就是把一个文件分成这么大的块来进行上传,看来问题就是出在这儿了。把这项设置的值加大,改成10mb或者100mb,再测试就没这问题了。

说下原因:
chunk_size 可以把文件分成多块来上传,这样可以绕过服务器允许的最大上传文件大小的限制,前提是需要上传接口支持文件续传。这个参数一般设置成与服务器允许的最大文件大小一致就可以了,或者是上传接口支持文件续传。

关于在IIS下的.NET网站出现应用池挂掉的Bug排查方法

环境:MVC4+IIS7

现象:测试的时候没有显现出来,当运行到生产环境出现大量访问量的情况下,会出现如下错误:


如果应用程序池挂掉的话,可以肯定的是,代码出现了很严重的错误,导致程序挂了,原因可能是死循环之类的。而又是个别现象引起,测不出来,只能想其他的办法了。

解决方法

首先,在服务器端:

1.开启Windows Error Reporting Service服务

2.执行下面的注册表脚本,在w3wp.exe程序挂掉的时候,自动将dump文件保存到D:\dumps文件夹中:

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\w3wp.exe]
"DumpFolder"=hex(2):64,00,3a,00,5c,00,64,00,75,00,6d,00,70,00,73,00,00,00
"DumpCount"=dword:00000002
"DumpType"=dword:00000002

3.记录出问题的w3wp.exe程序的pid,把生成的dump文件复制到本地,进行调试。

之后,在本机:

1.双击从服务器上拿下来的dump文件,使用vs(2013、2015等,2010、2008没有测试过)打开,之后会显示出异常摘要等信息。

2.点击右侧“操作”列中的“设置符号路径”菜单

3.通过菜单“视图”——“解决方案资源管理器”,打开解决方案管理器,之后打开解决方案的属性页,选择调试源文件,之后新加一行,选择对应的源代码(项目)文件夹,之后确定保存。

4.回到dump文件摘要页面,通过右侧“操作”菜单下的“使用仅限托管进行调试”菜单进行调试,可以定位到问题代码位置进行解决处理。当然根据问题的不同,还可以选择其他几个调试方法。

以上。

.Net Core系列教程(五)—— Token Base身份认证

在ASP.Net Core中实现一个Token Base身份认证,使用场景主要就是Web API下,可以调用Web API的不止是浏览器,还有各种各样的客户端,有些客户端没有Cookies,也无法使用Session。这时候就需要Token来救场了,相比Cookies,Token更开放,而安全性也要比Cookies高很多。

下面使用微软JwtSecurityTokenHandler来实现一个基于beare token的身份认证。

1.创建辅助类:

在项目中,新建一个Auth文件夹,在Auth文件夹中添加一个RSAKeyHelper类:

using System.Security.Cryptography;
namespace Biz126.WebAPI.Auth
{
    public class RSAKeyHelper
    {
        public static RSAParameters GenerateKey()
        {
            using (var key = new RSACryptoServiceProvider(2048))
            {
                return key.ExportParameters(true);
            }
        }
    }
}

和TokenAuthOption类:

using Microsoft.IdentityModel.Tokens;
namespace Biz126.WebAPI.Auth
{
    public class TokenAuthOption
    {
        public static string Audience { get; } = "ExampleAudience";
        public static string Issuer { get; } = "ExampleIssuer";
        public static RsaSecurityKey Key { get; } = new RsaSecurityKey(RSAKeyHelper.GenerateKey());
        public static SigningCredentials SigningCredentials { get; } = new SigningCredentials(Key, SecurityAlgorithms.RsaSha256Signature);
        public static TimeSpan ExpiresSpan { get; } = TimeSpan.FromMinutes(20);
    }
}

2.修改Startup.cs文件:

打开Startup.cs文件,在ConfigureServices中添加:

            services.AddAuthorization(auth =>
            {
                auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
                    .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme‌)
                    .RequireAuthenticatedUser().Build());
            });

完整的ConfigureServices方法:

        public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddApplicationInsightsTelemetry(Configuration);
            services.Configure<Biz126.Models.ConnectionStrings>(Configuration.GetSection("ConnectionStrings"));    //这个是取数据库配置,与本例无关
            services.AddAuthorization(auth =>
            {
                auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
                    .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme‌)
                    .RequireAuthenticatedUser().Build());
            });

            services.AddMvc();
        }

修改Configure方法,在其中增加:

            app.UseExceptionHandler(appBuilder => {
                appBuilder.Use(async (context, next) => {
                    var error = context.Features[typeof(IExceptionHandlerFeature)] as IExceptionHandlerFeature;
                    //when authorization has failed, should retrun a json message to client
                    if (error != null && error.Error is SecurityTokenExpiredException)
                    {
                        context.Response.StatusCode = 401;
                        context.Response.ContentType = "application/json";
                        await context.Response.WriteAsync(JsonConvert.SerializeObject(
                            //new { authenticated = false, tokenExpired = true }
                            new { Status = false, Message = "Token已失效", Code = -401, Result = new { tokenExpired = true } }
                        ));
                    }
                    //when orther error, retrun a error message json to client
                    else if (error != null && error.Error != null)
                    {
                        context.Response.StatusCode = 500;
                        context.Response.ContentType = "application/json";
                        await context.Response.WriteAsync(JsonConvert.SerializeObject(
                            //new { success = false, error = error.Error.Message }
                            new { Status = false, Code = -500, Message = error.Error.Message }
                        ));
                    }
                    //when no error, do next.
                    else await next();
                });
            });
            app.UseExceptionHandler(appBuilder => {
                appBuilder.Use(async (context, next) => {
                    var error = context.Features[typeof(IExceptionHandlerFeature)] as IExceptionHandlerFeature;
                    //when authorization has failed, should retrun a json message to client
                    if (error != null && error.Error is SecurityTokenExpiredException)
                    {
                        context.Response.StatusCode = 401;
                        context.Response.ContentType = "application/json";
                        await context.Response.WriteAsync(JsonConvert.SerializeObject(
                            new { Status = false, Message = "Token已失效", Code = -401, Result = new { tokenExpired = true } }
                        ));
                    }
                    //when orther error, retrun a error message json to client
                    else if (error != null && error.Error != null)
                    {
                        context.Response.StatusCode = 500;
                        context.Response.ContentType = "application/json";
                        await context.Response.WriteAsync(JsonConvert.SerializeObject(
                            new { Status = false, Code = -500, Message = error.Error.Message }
                        ));
                    }
                    //when no error, do next.
                    else await next();
                });
            });
            //应用JwtBearerAuthentication
            app.UseJwtBearerAuthentication(new JwtBearerOptions
            {
                TokenValidationParameters = new TokenValidationParameters
                {
                    IssuerSigningKey = TokenAuthOption.Key,
                    ValidAudience = TokenAuthOption.Audience,
                    ValidIssuer = TokenAuthOption.Issuer,
                    ValidateIssuerSigningKey = true,
                    ValidateLifetime = true,
                    ClockSkew = TimeSpan.FromMinutes(0)
                }
            });

完整的Configure方法:

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();
            app.UseApplicationInsightsRequestTelemetry();
            app.UseApplicationInsightsExceptionTelemetry();
            app.UseExceptionHandler(appBuilder => {
                appBuilder.Use(async (context, next) => {
                    var error = context.Features[typeof(IExceptionHandlerFeature)] as IExceptionHandlerFeature;
                    //when authorization has failed, should retrun a json message to client
                    if (error != null && error.Error is SecurityTokenExpiredException)
                    {
                        context.Response.StatusCode = 401;
                        context.Response.ContentType = "application/json";
                        await context.Response.WriteAsync(JsonConvert.SerializeObject(
                            //new { authenticated = false, tokenExpired = true }
                            new { Status = false, Message = "Token已失效", Code = -401, Result = new { tokenExpired = true } }
                        ));
                    }
                    //when orther error, retrun a error message json to client
                    else if (error != null && error.Error != null)
                    {
                        context.Response.StatusCode = 500;
                        context.Response.ContentType = "application/json";
                        await context.Response.WriteAsync(JsonConvert.SerializeObject(
                            //new { success = false, error = error.Error.Message }
                            new { Status = false, Code = -500, Message = error.Error.Message }
                        ));
                    }
                    //when no error, do next.
                    else await next();
                });
            });
            app.UseExceptionHandler(appBuilder => {
                appBuilder.Use(async (context, next) => {
                    var error = context.Features[typeof(IExceptionHandlerFeature)] as IExceptionHandlerFeature;
                    //when authorization has failed, should retrun a json message to client
                    if (error != null && error.Error is SecurityTokenExpiredException)
                    {
                        context.Response.StatusCode = 401;
                        context.Response.ContentType = "application/json";
                        await context.Response.WriteAsync(JsonConvert.SerializeObject(
                            new { Status = false, Message = "Token已失效", Code = -401, Result = new { tokenExpired = true } }
                        ));
                    }
                    //when orther error, retrun a error message json to client
                    else if (error != null && error.Error != null)
                    {
                        context.Response.StatusCode = 500;
                        context.Response.ContentType = "application/json";
                        await context.Response.WriteAsync(JsonConvert.SerializeObject(
                            new { Status = false, Code = -500, Message = error.Error.Message }
                        ));
                    }
                    //when no error, do next.
                    else await next();
                });
            });
            app.UseJwtBearerAuthentication(new JwtBearerOptions
            {
                TokenValidationParameters = new TokenValidationParameters
                {
                    IssuerSigningKey = TokenAuthOption.Key,
                    ValidAudience = TokenAuthOption.Audience,
                    ValidIssuer = TokenAuthOption.Issuer,
                    ValidateIssuerSigningKey = true,
                    ValidateLifetime = true,
                    ClockSkew = TimeSpan.FromMinutes(0)
                }
            });
            app.UseMvc();
        }

3.登录授权接口

在Controllers中,增加TokenAuthController的Web API控制器,在该控制器下添加如下方法:

        /// <summary>
        /// 生成Token
        /// </summary>
        /// <param name="user"></param>
        /// <param name="serviceid"></param>
        /// <param name="device"></param>
        /// <param name="expires"></param>
        /// <returns></returns>
        private string GenerateToken(Biz126.Customer.Models.Detail user,string serviceid,string device, DateTime expires)
        {
            var handler = new JwtSecurityTokenHandler();
            ClaimsIdentity identity = new ClaimsIdentity(
                new GenericIdentity(user.UserName, "TokenAuth"),
                new[] {
                    new Claim("ID", user._Id.ToString()),
                    new Claim("TrueName",user.TrueName),
                    new Claim("ServiceId",serviceid),
                    new Claim("Device",device)  //绑定硬件号
                }
            );
            var securityToken = handler.CreateToken(new SecurityTokenDescriptor
            {
                Issuer = TokenAuthOption.Issuer,
                Audience = TokenAuthOption.Audience,
                SigningCredentials = TokenAuthOption.SigningCredentials,
                Subject = identity,
                Expires = expires
            });
            return handler.WriteToken(securityToken);
        }

正如注释中所说的,该方法用于生成Token。

还是在该控制器下,继续添加GetAuthorize方法,用于取得授权,代码如下:

        [HttpPost]
        public Biz126.Models.ResultModel<object> GetAuthorize(Biz126.Authorization.Models.UserAuth user)
        {
            var result = new Biz126.Models.ResultModel<object>();
            var log = new Biz126.Customer.Models.Login() { UserName = user.UserName, Password = user.Password };
            var login = _users.Login(log);    //登录

            if (login.Status)
            {
                //用户账号状态正常
                //1.查看该用户有几个有效的该授权
                //2.已经开通了几个
                //3.在剩余范围内
                //4.查看该机器是否已经有过授权
                //5.如果已经有过授权,更新Token,如果没有过授权,增加新授权
                var requestAt = DateTime.Now;
                var expiresIn = requestAt + TokenAuthOption.ExpiresSpan;    //过期时间(正常为授权结束日期)
                var token = GenerateToken(login.Result,user.ServiceId,user.Device, expiresIn);
                result.Result = new { requestAt = requestAt, expiresIn = TokenAuthOption.ExpiresSpan.TotalSeconds, accessToken = token };
                result.Status = true;
                result.Message = "success";
                result.Code = 0;
            }
            else
            {
                result.Status = false;
                result.Message = "用户名或密码错误";
                result.Code = -403;
            }
            return result;
        }

4.验证授权:

在Controllers中新建一个CheckAuthController的Web API控制器,添加下面的方法:

        [Authorize("Bearer")]
        public string Post()
        {
            var claimsIdentity = User.Identity as ClaimsIdentity;
            var id = claimsIdentity.Claims.FirstOrDefault(c => c.Type == "ID").Value;
            var device= claimsIdentity.Claims.FirstOrDefault(c => c.Type == "Device").Value;
            return $"Hello! {HttpContext.User.Identity.Name}, your Device is:{device}";
        }

5.测试:

打开Postman,先访问/api/TokenAuth/GetAuthorize,使用用户名和密码进行登录,接口会返回生成的Token,记下返回的Token。继续使用Postman工具,访问接口/api/CheckAuth,在Headers中,添加:Authorization:Bearer 上一步生成的Token,如下图所示

要注意“Bearer”与后面的Token之间有一个空格,之后提交请求,可以看到验证通过并给返回相应的信息。

上面代码只是一个例子,具体可以灵活的运用到自己的项目中。

以上。

sql日期格式化

  0   或   100   (*)     默认值   mon   dd   yyyy   hh:miAM(或   PM)     
  1   101   美国   mm/dd/yyyy     
  2   102   ANSI   yy.mm.dd     
  3   103   英国/法国   dd/mm/yy     
  4   104   德国   dd.mm.yy     
  5   105   意大利   dd-mm-yy     
  6   106   -   dd   mon   yy     
  7   107   -   mon   dd,   yy     
  8   108   -   hh:mm:ss     
  -   9   或   109   (*)     默认值   +   毫秒   mon   dd   yyyy   hh:mi:ss:mmmAM(或   PM)     
  10   110   美国   mm-dd-yy     
  11   111   日本   yy/mm/dd     
  12   112   ISO   yymmdd     
  -   13   或   113   (*)     欧洲默认值   +   毫秒   dd   mon   yyyy   hh:mm:ss:mmm(24h)     
  14   114   -   hh:mi:ss:mmm(24h)     
  -   20   或   120   (*)     ODBC   规范   yyyy-mm-dd   hh:mm:ss[.fff]     
  -   21   或   121   (*)     ODBC   规范(带毫秒)   yyyy-mm-dd   hh:mm:ss[.fff]     
  -   126(***)   ISO8601   yyyy-mm-dd   Thh:mm:ss:mmm(不含空格)     
  -   130*   科威特   dd   mon   yyyy   hh:mi:ss:mmmAM     
  -   131*   科威特   dd/mm/yy   hh:mi:ss:mmmAM   

Sql Server 中一个非常强大的日期格式化函数

Select CONVERT(varchar(100), GETDATE(), 0): 05 16 2006 10:57AM
Select CONVERT(varchar(100), GETDATE(), 1): 05/16/06
Select CONVERT(varchar(100), GETDATE(), 2): 06.05.16
Select CONVERT(varchar(100), GETDATE(), 3): 16/05/06
Select CONVERT(varchar(100), GETDATE(), 4): 16.05.06
Select CONVERT(varchar(100), GETDATE(), 5): 16-05-06
Select CONVERT(varchar(100), GETDATE(), 6): 16 05 06
Select CONVERT(varchar(100), GETDATE(), 7): 05 16, 06
Select CONVERT(varchar(100), GETDATE(), 8): 10:57:46
Select CONVERT(varchar(100), GETDATE(), 9): 05 16 2006 10:57:46:827AM
Select CONVERT(varchar(100), GETDATE(), 10): 05-16-06
Select CONVERT(varchar(100), GETDATE(), 11): 06/05/16
Select CONVERT(varchar(100), GETDATE(), 12): 060516
Select CONVERT(varchar(100), GETDATE(), 13): 16 05 2006 10:57:46:937
Select CONVERT(varchar(100), GETDATE(), 14): 10:57:46:967
Select CONVERT(varchar(100), GETDATE(), 20): 2006-05-16 10:57:47
Select CONVERT(varchar(100), GETDATE(), 21): 2006-05-16 10:57:47.157
Select CONVERT(varchar(100), GETDATE(), 22): 05/16/06 10:57:47 AM
Select CONVERT(varchar(100), GETDATE(), 23): 2006-05-16
Select CONVERT(varchar(100), GETDATE(), 24): 10:57:47
Select CONVERT(varchar(100), GETDATE(), 25): 2006-05-16 10:57:47.250
Select CONVERT(varchar(100), GETDATE(), 100): 05 16 2006 10:57AM
Select CONVERT(varchar(100), GETDATE(), 101): 05/16/2006
Select CONVERT(varchar(100), GETDATE(), 102): 2006.05.16
Select CONVERT(varchar(100), GETDATE(), 103): 16/05/2006
Select CONVERT(varchar(100), GETDATE(), 104): 16.05.2006
Select CONVERT(varchar(100), GETDATE(), 105): 16-05-2006
Select CONVERT(varchar(100), GETDATE(), 106): 16 05 2006
Select CONVERT(varchar(100), GETDATE(), 107): 05 16, 2006
Select CONVERT(varchar(100), GETDATE(), 108): 10:57:49
Select CONVERT(varchar(100), GETDATE(), 109): 05 16 2006 10:57:49:437AM
Select CONVERT(varchar(100), GETDATE(), 110): 05-16-2006
Select CONVERT(varchar(100), GETDATE(), 111): 2006/05/16
Select CONVERT(varchar(100), GETDATE(), 112): 20060516
Select CONVERT(varchar(100), GETDATE(), 113): 16 05 2006 10:57:49:513
Select CONVERT(varchar(100), GETDATE(), 114): 10:57:49:547
Select CONVERT(varchar(100), GETDATE(), 120): 2006-05-16 10:57:49
Select CONVERT(varchar(100), GETDATE(), 121): 2006-05-16 10:57:49.700
Select CONVERT(varchar(100), GETDATE(), 126): 2006-05-16T10:57:49.827
Select CONVERT(varchar(100), GETDATE(), 130): 18 ???? ?????? 1427 10:57:49:907AM
Select CONVERT(varchar(100), GETDATE(), 131): 18/04/1427 10:57:49:920AM

常用:

Select CONVERT(varchar(100), GETDATE(), 8): 10:57:46
Select CONVERT(varchar(100), GETDATE(), 24): 10:57:47
Select CONVERT(varchar(100), GETDATE(), 108): 10:57:49
Select CONVERT(varchar(100), GETDATE(), 12): 060516
Select CONVERT(varchar(100), GETDATE(), 23): 2006-05-16

SQL中CONVERT转化函数的用法
CONVERT的使用方法:
////////////////////////////////////////////////////////////////////////////////////////
格式:

CONVERT(data_type,e­xpression[,style])

说明:
此样式一般在时间类型(datetime,smalldatetime)与字符串类型(nchar,nvarchar,char,varchar)
相互转换的时候才用到.

例子:

Select CONVERT(varchar(30),getdate(),101) now

结果为

 now
 ---------------------------------------
 09/15/2001

/////////////////////////////////////////////////////////////////////////////////////

style数字在转换时间时的含义如下

Style(2位表示年份)Style(4位表示年份)输入输出格式
-0 or 100mon dd yyyy hh:miAM(或PM)
1101mm/dd/yy
2102yy-mm-dd
3103dd/mm/yy
4104dd-mm-yy
5105dd-mm-yy
6106dd mon yy
7107mon dd,yy
8108hh:mm:ss
-9 or 109mon dd yyyy hh:mi:ss:mmmmAM(或PM)
10110mm-dd-yy
11111yy/mm/dd
12112yymmdd
-13 or 113dd mon yyyy hh:mi:ss:mmm(24小时制)
14114hh:mi:ss:mmm(24小时制)
-20 or 120yyyy-mm-dd hh:mi:ss(24小时制)
-21 or 121yyyy-mm-dd hh:mi:ss:mmm(24小时制)

原文:http://www.cnblogs.com/hantianwei/archive/2009/12/03/1616148.html

分类

最新文章

最近回复

归档

标签云

C# .net core asp.net 情感 SQL mongodb sql server EasyUI linux 身份验证 typecho .net sql注入 安全 kms 激活 MVC https IIS 高并发 IE 坑爹 服务器 mysql Combobox Datagrid 口语 数据抓取 远程下载

其它