JavaScript - 获取系统短日期格式

17

有没有办法在JavaScript中获取系统短日期格式?

例如,系统的短日期格式是美国格式,如m/d/Y还是欧洲格式,如d/m/Y。

请注意: 这不是关于格式化日期或基于地理位置计算日期的问题,而是关于从操作系统/系统获取格式的问题。


1
好问题。我认为没有直接告诉的方法,但是也许您可以通过使用 .toLocaleDateString() 格式化已知日期,然后测试结果字符串是否以月份开头来解决它。 - nnnnnn
1
看看这个帖子是否有帮助 https://dev59.com/onE95IYBdhLWcg3wQ7qc - krishnakumarp
尝试使用 date.toLocaleDateString()。 - hayat
1
曾经历过这种情况,最终在应用程序的数据库中记录用户选择,并在组合框中提供一些标准格式的简短列表。但是,浏览器对此的支持非常差劲。 - Peter Wone
这个回答解决了你的问题吗?使用JavaScript获取本地短日期格式 - Jack Miller
显示剩余5条评论
8个回答

5

经过一番研究,我得出结论,从技术上讲,获取区域设置(包括日期格式)是不可能的,但您可以选择以下几个选项之一:
a)使用已经提到但过时的“toLocaleString()”函数:

var myDate = new Date(1950, 01, 21, 22, 23, 24, 225);
var myDateFormat = myDate.toLocaleString();
alert (myDateFormat);

问题:
1)你无法使用“myDateFormat.replace”获取日期掩码,因为月份不是以“01”,“02”等数字形式存储在字符串中, 而是根据区域设置以文本形式存储(例如英语中的“February”,但在希腊语中为“Φεβρουάριος”,而在克林贡语中则是谁知道)。
2)在不同的浏览器中有不同的行为
3)在不同的操作系统和浏览器版本上有不同的行为...

b)使用toISOString()函数代替toLocaleString()。您将得到一个日期,从中可以确定日期的哪个部分(即该字符串中的“月份”或“日期”在哪里)。您也可以使用getUTCDate()getUTCMonth()getUTCDay()函数进行操作。您仍然无法确定客户端使用的日期格式,但可以确定您在抓取日期时要使用哪个年/月/日等;使用上述代码测试我在此处提到的函数以了解您可以期望什么。

c)阅读不同浏览器中toLocaleString()的不一致行为文章,并使用在其中描述的(依我之见很棒的)解决方案


嗨Mark,谢谢你的答案。我同意你的观点,但这仍然依赖于浏览器。 - WooDzu
如果你指的是选项'c',那么是的,你是正确的,问题被标记为浏览器问题,但解决方案更通用。另一方面,如果我是你,我会选择'b'。如果必须知道日期格式掩码,还有另一个选项:"myDateFormat.replace("1950", "yyyy");"等等 - 但对于月份,您需要找到字符串的起始和结束位置,并将该范围替换为"mm" - 这使得您的脚本变得有点太复杂,甚至可能达不到您的目标... - user2299169
唯一的问题是,如果例如我的系统时钟、Excel电子表格和许多其他应用程序都使用d/m/Y格式,而我的浏览器因某种原因(是的,它确实会这样)检测到'en-US',那么它将使用en-US格式,即m/d/Y。 - WooDzu
1
我理解。但是使用JavaScript解决方法的问题在于,区域设置可能在每个系统上都是独特的,因为用户可以自定义显示的日期/时间格式。例如,我的计算机具有en-US区域设置(我喜欢将其设置为EN OS与EN键盘),但我将我的日期/时间格式设置为匈牙利语(“yyyy.mm.dd,DDDD”和“HH:mm:ss”),因为我是匈牙利人。而这种格式并不是匈牙利的标准格式。我只是喜欢这样...这就是为什么“不”是你问题的答案。不可能编写一个在所有系统上完美运行的脚本来“提取”日期格式。 - user2299169
顺便提一句,一个空的type=time输入会显示与系统配置完全相同的格式,但我还没有找到从JavaScript中检索它的方法。 - WooDzu

2

对于我的情况,我使用了一个自定义日期,我知道哪一天是几号,哪个月份,哪一年,因此可以通过简单的替换语句实现。

let customDate = new Date(2222, 11, 18);
let strDate = customDate.toLocaleDateString();
let format = strDate
    .replace("12", "MM")
    .replace("18", "DD")
    .replace("2222", "yyyy");

1
使用这种方法,您可能会错误地使用“dd”而不是“d”。 - Jack Miller
1
"mm" 是代表分钟而不是月份的占位符! - Jack Miller

1

这里可以找到一个非常好但有点长的答案:https://dev59.com/onE95IYBdhLWcg3wQ7qc#9893752

这里有一个更短的答案:

let customDate = new Date(2222, 3, 8);
let strDate = customDate.toLocaleDateString();
let format = strDate
    .replace("04", "MM")
    .replace("4", "M")
    .replace("08", "dd")
    .replace("8", "d")
    .replace("2222", "yyyy")
    .replace("22", "yy");
console.log(format);

我们创建一个已知日期的日期对象,然后解析结果。

首先,我们查找"04"(对应于日期定义中的3),这将是两位数月份格式MM。如果未找到,则必须为单个数字格式M。之后对日和年做同样的操作。


0

它应该能完成工作...

function getSystemDateLocale(){
    let testDate = (new Date('2000-1-30')).toLocaleDateString()
    if (testDate.substring(0,2) == '30') return 'EU'
    else return 'US'
}

虽然这段代码片段可能解决了问题,但它并没有解释为什么或者如何回答这个问题。请在你的代码中包含一个解释,因为这真的有助于提高你的帖子质量。记住,你正在为未来的读者回答问题,而那些人可能不知道你的代码建议的原因。 - Luca Kiebel

0

这是不可能的。您可以从用户浏览器获取文化信息,并使用一些JS库将其转换为正确的日期格式。http://code.google.com/p/datejs/


请注意我的问题上的注释。 - WooDzu
1
答案是否定的。这是不可能的,我只能给你一些提示。 :) - Reno

0
我编写了一个函数来确定客户端的日期格式。该函数确定日期格式分隔符,并确定日期格式的第一、第二和第三部分。
getDateFormat(){
    // initialize date value "31st January 2019"
    var my_date = new Date(2019,0,31);
    console.log(my_date.toLocaleDateString());
    // Initialize variables
    var separator="";
    var first="";
    var second="";
    var third="";
    var date_parts = [];

    // get separator : "-", "/" or " ", format based on toLocaleDateString function        
    if (my_date.toLocaleDateString().split("-").length==3){
        separator = " - ";
        date_parts = my_date.toLocaleDateString().split("-");
    } 
    if (my_date.toLocaleDateString().split("/").length == 3) {
        separator = " / ";
        date_parts = my_date.toLocaleDateString().split("/");
    } 
    if (my_date.toLocaleDateString().split(" ").length == 3) {
        separator = " ";
        date_parts = my_date.toLocaleDateString().split(" ");
    } 

    // get first part        
    if (date_parts[0]==2019){
        first ="yyyy";
    } else if (date_parts[0] == 31){
        first = "dd";
    } else{
        if (date_parts[0].length<=2){
            first ="mm";
        }
        else{
            first="mmm";
        }
    }

    // get second part        
    if (date_parts[1] == 2019) {
        second = "yyyy";
    } else if (date_parts[1] == 31) {
        second = "dd";
    } else {
        if (date_parts[1].length <= 2) {
            second = "mm";
        }
        else {
            second = "mmm";
        }
    }

    // get third part        
    if (date_parts[2] == 2019) {
        third = "yyyy";
    } else if (date_parts[2] == 31) {
        third = "dd";
    } else {
        if (date_parts[2].length <= 2) {
            third = "mm";
        }
        else {
            third = "mmm";
        }
    }

    // assembly
    var format = first + separator + second + separator + third;
    console.log(format);
    return format;
}

0
我已经创建了一个解决方法来确定用户的浏览器使用的格式。这是用C#编写的,但逻辑相同:
以下是步骤:
  1. 首先尝试将用户浏览器的日期转换为美国格式(mm-dd-yyyy)。Convert.ToDateTime使用的是美国日期格式。

  2. 如果失败了,这意味着用户使用的是欧洲格式(dd-mm-yyyy)。但是,这只涵盖了13到31号,因为这不是一个有效的月份。

  3. 如果转换成功,请进行另一个检查,以确定转换后的日期是否在当前UTC日期+1天(以覆盖UTC+14)和当前UTC日期-1天(以覆盖UTC-12)之间。https://www.timeanddate.com/time/current-number-time-zones.html

  4. 如果转换后的日期超出了当前日期范围,则表示用户的浏览器使用的是欧洲格式(dd-mm-yyyy),如果需要,可以将其转换为美国格式。

             string localeDateString = "01/11/2020"; // 例如,输入使用欧洲格式(dd-mm-yyyy)
             var localeDate = new DateTime();
    
             try
             {
                 localeDate = Convert.ToDateTime(localeDateString);
                 //var checkTheFormatOfDateInput = localeDate.ToLongDateString();
                 var currentDateTime = DateTime.UtcNow;
                 //var currentDateTime = Convert.ToDateTime("11/01/2020");
                 //var checkTheFormatOfCurrentDate = Convert.ToDateTime("11/01/2020").ToLongDateString();
                 var currentDateTimePositive = currentDateTime.AddDays(1);
                 var currentDateTimeNegative = currentDateTime.AddDays(-1);
    
                 var outOfCurrentDateRange = !(localeDate.Ticks > currentDateTimeNegative.Ticks && localeDate.Ticks < currentDateTimePositive.Ticks);
    
                 if (outOfCurrentDateRange)
                 {
                     localeDate = DateTime.ParseExact(localeDateString, "dd/MM/yyyy", CultureInfo.InvariantCulture);
                 }
             }
             catch
             {
                 localeDate = DateTime.ParseExact(localeDateString, "dd/MM/yyyy", CultureInfo.InvariantCulture);
             }
    
             //var checkTheEndResultFormat = localeDate.ToLongDateString();
    
以下是封装在方法中的干净代码:
    private DateTime ConvertAmericanOrEuropeanDateFormatToAmericanDateFormat(string localeDateString)
    {
        var localeDate = new DateTime();

        try
        {
            localeDate = Convert.ToDateTime(localeDateString);
            var currentDateTime = DateTime.UtcNow;
            var currentDateTimePositive = currentDateTime.AddDays(1);
            var currentDateTimeNegative = currentDateTime.AddDays(-1);

            var outOfCurrentDateRange = !(localeDate.Ticks > currentDateTimeNegative.Ticks && localeDate.Ticks < currentDateTimePositive.Ticks);

            if (outOfCurrentDateRange)
            {
                localeDate = DateTime.ParseExact(localeDateString, "dd/MM/yyyy", CultureInfo.InvariantCulture);
            }
        }
        catch
        {
            localeDate = DateTime.ParseExact(localeDateString, "dd/MM/yyyy", CultureInfo.InvariantCulture);
        }

        return localeDate;
    }

-1
使用 Date.CultureInfo.formatPatterns.shortDate。

嗨,刚刚检查了一下。你从哪里获取CultureInfo?Firefox和Chrome中的Date对象没有它。 - WooDzu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接