如何在 JavaScript 中将公历日期更改为波斯日期?

Posted

技术标签:

【中文标题】如何在 JavaScript 中将公历日期更改为波斯日期?【英文标题】:How to change Gregorian date to Persian date in JavaScript? 【发布时间】:2016-06-04 21:31:56 【问题描述】:

谁能帮我在 javascript 中将公历日期更改为波斯语?我想在 html 和 JavaScript 中使用它。

【问题讨论】:

这似乎是你的答案 (Link)。 您可以在此处查看***.com/a/54838854/11082300 答案,它可以解决此问题。 【参考方案1】:

你可以使用toLocaleDateString();

let today = new Date().toLocaleDateString('fa-IR');
console.log(today);

fa-IR 代表波斯-伊朗,

其他日期如下:

en-US: 英文版

hi-IN: 印地语

...

您也可以将选项设置为第二个参数,例如:

let options =  year: 'numeric', month: 'long', day: 'numeric' ;
new Date().toLocaleDateString('fa-IR', options);

为了将字符转换为拉丁数字,您可以这样做:

let today = new Date().toLocaleDateString('fa-IR'); today.replace(/([۰-۹])/g, token => String.fromCharCode(token.charCodeAt(0) - 1728));

【讨论】:

new Date().toLocaleDateString('fa-IR',year:'numeric',month:'2-digit',day:'2-digit',formatMatcher:'basic') 我如何反转我使用您的解决方案,但我需要最后反转日期。我的意思是假设我有“1398/10/17”,现在我需要系统的有效日期? @MostafaSaadatnia 您应该将日期和时间以时间戳格式保存在数据库中,并且仅使用此方法将日期和时间显示为波斯语或其他日期。永远不要将此格式保存到数据库。 还要注意浏览器的支持:caniuse.com/date-tolocaledatestring,如果需要经过良好测试的库,我建议:github.com/babakhani/PersianDate 您可以尝试使用这种方法将波斯日期转换为 Javascript 中的任何其他 18 个日历日期:***.com/questions/24989984/…【参考方案2】:

getPersianDate = (format) =>  
  let week = new Array("يكشنبه", "دوشنبه", "سه شنبه", "چهارشنبه", "پنج شنبه", "جمعه", "شنبه")
  let months = new Array("فروردين", "ارديبهشت", "خرداد", "تير", "مرداد", "شهريور", "مهر", "آبان", "آذر", "دي", "بهمن", "اسفند");
  let today = new Date();
  let d = today.getDay();
  let day = today.getDate();
  let month = today.getMonth() + 1;
  let year = today.getYear();
  year = (window.navigator.userAgent.indexOf('MSIE') > 0) ? year : 1900 + year;
  if (year == 0) 
      year = 2000;
  
  if (year < 100) 
      year += 1900;
  
  y = 1;
  for (i = 0; i < 3000; i += 4) 
      if (year == i) 
          y = 2;
      
  
  for (i = 1; i < 3000; i += 4) 
      if (year == i) 
          y = 3;
      
  
  if (y == 1) 
      year -= ((month < 3) || ((month == 3) && (day < 21))) ? 622 : 621;
      switch (month) 
          case 1:
              (day < 21) ? (month = 10, day += 10) : (month = 11, day -= 20);
              break;
          case 2:
              (day < 20) ? (month = 11, day += 11) : (month = 12, day -= 19);
              break;
          case 3:
              (day < 21) ? (month = 12, day += 9) : (month = 1, day -= 20);
              break;
          case 4:
              (day < 21) ? (month = 1, day += 11) : (month = 2, day -= 20);
              break;
          case 5:
          case 6:
              (day < 22) ? (month -= 3, day += 10) : (month -= 2, day -= 21);
              break;
          case 7:
          case 8:
          case 9:
              (day < 23) ? (month -= 3, day += 9) : (month -= 2, day -= 22);
              break;
          case 10:
              (day < 23) ? (month = 7, day += 8) : (month = 8, day -= 22);
              break;
          case 11:
          case 12:
              (day < 22) ? (month -= 3, day += 9) : (month -= 2, day -= 21);
              break;
          default:
              break;
      
  
  if (y == 2) 
      year -= ((month < 3) || ((month == 3) && (day < 20))) ? 622 : 621;
      switch (month) 
          case 1:
              (day < 21) ? (month = 10, day += 10) : (month = 11, day -= 20);
              break;
          case 2:
              (day < 20) ? (month = 11, day += 11) : (month = 12, day -= 19);
              break;
          case 3:
              (day < 20) ? (month = 12, day += 10) : (month = 1, day -= 19);
              break;
          case 4:
              (day < 20) ? (month = 1, day += 12) : (month = 2, day -= 19);
              break;
          case 5:
              (day < 21) ? (month = 2, day += 11) : (month = 3, day -= 20);
              break;
          case 6:
              (day < 21) ? (month = 3, day += 11) : (month = 4, day -= 20);
              break;
          case 7:
              (day < 22) ? (month = 4, day += 10) : (month = 5, day -= 21);
              break;
          case 8:
              (day < 22) ? (month = 5, day += 10) : (month = 6, day -= 21);
              break;
          case 9:
              (day < 22) ? (month = 6, day += 10) : (month = 7, day -= 21);
              break;
          case 10:
              (day < 22) ? (month = 7, day += 9) : (month = 8, day -= 21);
              break;
          case 11:
              (day < 21) ? (month = 8, day += 10) : (month = 9, day -= 20);
              break;
          case 12:
              (day < 21) ? (month = 9, day += 10) : (month = 10, day -= 20);
              break;
          default:
              break;
      
  
  if (y == 3) 
      year -= ((month < 3) || ((month == 3) && (day < 21))) ? 622 : 621;
      switch (month) 
          case 1:
              (day < 20) ? (month = 10, day += 11) : (month = 11, day -= 19);
              break;
          case 2:
              (day < 19) ? (month = 11, day += 12) : (month = 12, day -= 18);
              break;
          case 3:
              (day < 21) ? (month = 12, day += 10) : (month = 1, day -= 20);
              break;
          case 4:
              (day < 21) ? (month = 1, day += 11) : (month = 2, day -= 20);
              break;
          case 5:
          case 6:
              (day < 22) ? (month -= 3, day += 10) : (month -= 2, day -= 21);
              break;
          case 7:
          case 8:
          case 9:
              (day < 23) ? (month -= 3, day += 9) : (month -= 2, day -= 22);
              break;
          case 10:
              (day < 23) ? (month = 7, day += 8) : (month = 8, day -= 22);
              break;
          case 11:
          case 12:
              (day < 22) ? (month -= 3, day += 9) : (month -= 2, day -= 21);
              break;
          default:
              break;
      
  
  if(format===null || format===undefined)
    return `$week[d] $day $months[month - 1] $year`
  if(format==="y/m/d")
    return `$year/$month/$day`;
  if(format==="d/m/y")
    return `$day/$month/$year`;

console.log(getPersianDate());
console.log(getPersianDate("y/m/d"));
console.log(getPersianDate("d/m/y"));

【讨论】:

这不起作用 1994,09,19 不是 1373/07/27 正确转换是 1373/06/28 虽然它是一个很好的代码,但不幸的是它在某些日期不能正常工作,例如:1976/05/06 您好,Bashirpour 先生,如果您认为这些更改很好,我对您的代码进行了一些更改...接受我的更改。祝你一切顺利。 您好,Tejareh 先生。感谢您的良好编辑。 @MehrzadTejareh 即使是 Mehrzad Tejareh 先生编辑的版本也无法正常工作。例如,它将 2021/01/31 转换为 1399/12/12,这应该是 1399/11/12。【参考方案3】:

要获得 波斯数字

new Date().toLocaleDateString('fa-IR');
// ۱۳۹۹/۱/۲۳

要获得 拉丁数字

new Date().toLocaleDateString('fa-IR-u-nu-latn');
// 1399/1/23

Mohsen 在 cmets 中提到了这种方法,感谢他。


旧方法:拉丁数字

new Date().toLocaleDateString('fa-IR').replace(/([۰-۹])/g, token => String.fromCharCode(token.charCodeAt(0) - 1728));
// 1399/1/23

【讨论】:

如何替换工作?请给我解释一下。 Tnx 每个字符在内存中都是一个整数,可以参考ASCII编码了解更多。在 UTF-8 编码中,波斯数字的整数值减去 1728 是该数字的拉丁整数值。例如假设每个现有字符都是一个数组中的一个值,这个数组中波斯数字和拉丁数字之间的空间是 1728。@Hosein 解释得很好。谢谢,兄弟。 @AmirFo 要获得拉丁数字,只需使用u-nu- 后跟latn 添加要使用的编号系统即可:new Date().toLocaleDateString('fa-IR-u-nu-latn') @AmirFo 还可以看到这种将波斯日期转换为过日期的方法:***.com/questions/71421825/…【参考方案4】:

你可以像下面的代码一样简单地使用jalali-moment

import * as moment from 'jalali-moment';
let persianDate = moment("1989/1/24").locale('fa').format('YYYY/M/D'); // 1367/11/4

demo in plunker

【讨论】:

【参考方案5】:

您可以使用jalaali-js

Jalaali JavaScript

一些用于转换 Jalaali (Jalali, Persian, Khayyami, Khorshidi, Shamsi) 和公历系统 其他。

【讨论】:

【参考方案6】:

您也可以查看:JalaliJSCalendar (github)

JalaliJSCalendar 是一个基于 JavaScript 日期选择器和日历小部件 来自 Mihai Bazon 的“Dynarch DHTML 日历”。主要区别 两者之间是 JalaliJSCalendar 支持波斯语(AKA Hijri Shamsi) 日历也是伊朗官方日历。

它包含转换器 (jalali.js) 和 HTML 日期选择器/日历

【讨论】:

【参考方案7】:

此页面中的答案都不是正确的,它在某些情况下有效,但并不总是正确的!这适用于两种转换方法:

function gregorian_to_jalali(gy,gm,gd)
        var g_d_m=[0,31,59,90,120,151,181,212,243,273,304,334];
        var jy=(gy<=1600)?0:979;
        gy-=(gy<=1600)?621:1600;
        var gy2=(gm>2)?(gy+1):gy;
        var days=(365*gy) +(parseInt((gy2+3)/4)) -(parseInt((gy2+99)/100))
                +(parseInt((gy2+399)/400)) -80 +gd +g_d_m[gm-1];
        jy+=33*(parseInt(days/12053));
        days%=12053;
        jy+=4*(parseInt(days/1461));
        days%=1461;
        jy+=parseInt((days-1)/365);
        if(days > 365)days=(days-1)%365;
        var jm=(days < 186)?1+parseInt(days/31):7+parseInt((days-186)/30);
        var jd=1+((days < 186)?(days%31):((days-186)%30));
        return [jy,jm,jd];
    
function jalali_to_gregorian(jy,jm,jd)
        var gy=(jy<=979)?621:1600;
        jy-=(jy<=979)?0:979;
        var days=(365*jy) +((parseInt(jy/33))*8) +(parseInt(((jy%33)+3)/4))
                +78 +jd +((jm<7)?(jm-1)*31:((jm-7)*30)+186);
        gy+=400*(parseInt(days/146097));
        days%=146097;
        if(days > 36524)
            gy+=100*(parseInt(--days/36524));
            days%=36524;
            if(days >= 365)days++;
        
        gy+=4*(parseInt((days)/1461));
        days%=1461;
        gy+=parseInt((days-1)/365);
        if(days > 365)days=(days-1)%365;
        var gd=days+1;
        var sal_a=[0,31,((gy%4==0 && gy%100!=0) || (gy%400==0))?29:28,31,30,31,30,31,31,30,31,30,31];
        var gm
        for(gm=0;gm<13;gm++)
            var v=sal_a[gm];
            if(gd <= v)break;
            gd-=v;
        
        return [gy,gm,gd];
    

代码来自:https://github.com/hat3ck/Persian-Calendar-Qt

【讨论】:

是的,Mehdi 太棒了!就像第二个答案(Ali_Hr 的答案)对所有日期都适用。谢谢! @PureSilence 我直到最近才使用 toLocaleDateString,java 脚本 toLocaleDateString 在一年中的某些日子有波斯日期的问题,这就是为什么我分享这个答案并不总是正确的!但这个答案总是正确的 就我个人而言,我更喜欢你的代码,但是,我猜是 toLocaleDateString('fa-IR');总是正确的!您可以尝试以下事件: new Date('0777/09/09').toLocaleDateString('fa-IR');它返回 0156/06/18 并且您的函数返回 0156/06/19 我相信 0156/06/18 是正确的!但这并不重要,您的函数适用于所有较新的日期。 关于 0777 你是对的,这段代码不正确 反之,你可以试试这个方法,不用外部库***.com/questions/71421825/…【参考方案8】:

获取“jalali.js”from this link。

如果您的号码是波斯语格式,首先您必须将它们更改为英文格式,from this link

var
        persianNumbers = [/۰/g, /۱/g, /۲/g, /۳/g, /۴/g, /۵/g, /۶/g, /۷/g, /۸/g, /۹/g],
        arabicNumbers = [/٠/g, /١/g, /٢/g, /٣/g, /٤/g, /٥/g, /٦/g, /٧/g, /٨/g, /٩/g],
        fixNumbers = function (str) 
            if (typeof str === 'string') 
                for (var i = 0; i < 10; i++) 
                    str = str.replace(persianNumbers[i], i).replace(arabicNumbers[i], i);
                
            
         return str;
        ;

并使用下面的函数'getGregorian()'来转换日期。例如,我转换 '13۹۸/01/24' 日期:

function getGregorian () 
            var date = ("۱۳۹۸/۰۱/۲۴").split('/');
            y = Number( fixNumbers(date[0]) );
            m = Number( fixNumbers(date[1]) );
            d = Number( fixNumbers(date[2] ));

            gDate = toGregorian(y, m, d)
            gDate = gDate .gy + '/' + gDate .gm + '/' + gDate .gd;

        

【讨论】:

【参考方案9】:
function convertDate(stringArg) 
  const ETF = '۰۱۲۳۴۵۶۷۸۹';
  const ans = g2j(...stringArg.split('/').map(elem => +elem))
    .map(elem =>
      String(elem)
        .split('')
        .map(subElem => ETF[+subElem])
        .join('')
    )
    .join('/');
  return ans;

【讨论】:

仅代码的答案被认为是低质量的:请务必说明您的代码的作用以及它如何解决问题。如果您可以在帖子中添加更多信息,它将帮助提问者和未来的读者。见Explaining entirely code-based answers【参考方案10】:

您还可以使用以下函数返回 JSON 中的所有选项。阅读更多here。

options:
    weekday      -> [long | short | narrow]
    era          -> [long | short | narrow]
    timeZoneName -> [long | short]

    year         -> [numeric | 2-digit]
    month        -> [numeric | 2-digit | long | short | narrow]
    day          -> [numeric | 2-digit]
    hour         -> [numeric | 2-digit]
    minute       -> [numeric | 2-digit]
    second       -> [numeric | 2-digit]

to convert digits to Latin digits
.replace(/([۰-۹])/g, token => String.fromCharCode(token.charCodeAt(0) - 1728));

function PersianDate(raw_date) 
  date = new Date(raw_date);
  json_date = 
    'weekday': 
      'long': date.toLocaleDateString('fa-IR',  weekday: 'long' ),
      'short': date.toLocaleDateString('fa-IR',  weekday: 'short' ),
      'narrow': date.toLocaleDateString('fa-IR',  weekday: 'narrow' ),
    ,
    'era': 
      'long': date.toLocaleDateString('fa-IR',  era: 'long' ),
      'short': date.toLocaleDateString('fa-IR',  era: 'short' ),
      'narrow': date.toLocaleDateString('fa-IR',  era: 'narrow' ),
    ,
    'timeZoneName': 
      'long': date.toLocaleDateString('fa-IR',  timeZoneName: 'long' ),
      'short': date.toLocaleDateString('fa-IR',  timeZoneName: 'short' ),
    ,
    'year': 
      'numeric': date.toLocaleDateString('fa-IR',  year: 'numeric' ),
      '2-digit': date.toLocaleDateString('fa-IR',  year: '2-digit' ),
    ,
    'month': 
      'numeric': date.toLocaleDateString('fa-IR',  month: 'numeric' ),
      '2-digit': date.toLocaleDateString('fa-IR',  month: '2-digit' ),
      'long': date.toLocaleDateString('fa-IR',  month: 'long' ),
      'short': date.toLocaleDateString('fa-IR',  month: 'short' ),
      'narrow': date.toLocaleDateString('fa-IR',  month: 'narrow' ),
    ,
    'day': 
      'numeric': date.toLocaleDateString('fa-IR',  day: 'numeric' ),
      '2-digit': date.toLocaleDateString('fa-IR',  day: '2-digit' ),
    ,
    'hour': 
      'numeric': date.toLocaleDateString('fa-IR',  hour: 'numeric' ),
      '2-digit': date.toLocaleDateString('fa-IR',  hour: '2-digit' ),
    ,
    'minute': 
      'numeric': date.toLocaleDateString('fa-IR',  minute: 'numeric' ),
      '2-digit': date.toLocaleDateString('fa-IR',  minute: '2-digit' ),
    ,
    'second': 
      'numeric': date.toLocaleDateString('fa-IR',  second: 'numeric' ),
      '2-digit': date.toLocaleDateString('fa-IR',  second: '2-digit' ),
    
  
  return json_date;



date = PersianDate(new Date())

// Customize the output format
console.log(date['weekday']['narrow'] + ' ' + date['day']['2-digit'] + ' ' + date['month']['long'] + ' ' + date['year']['numeric']);
// Replatece Farsi digits with Latin ones, e.g. ۲۵ -> 25
console.log(date['day']['2-digit'].replace(/([۰-۹])/g, token => String.fromCharCode(token.charCodeAt(0) - 1728)));

【讨论】:

【参考方案11】:

你可以为 node js 安装这个 npm 包:

npm i jdate.js

或者为javascript和html导入这个脚本:

<script src="https://cdn.jsdelivr.net/npm/jdate.js"></script>

用法:

var date = new Date();
console.log( date.echoFa() );
console.log( date.echo() );
console.log( date );

~~>    شنبه، 25 دی 1400 - 19:22:22
~~>    Saturday January 15 2022 - 19:22:22
~~>    Sat Jan 15 2022 19:22:22 GMT+0330 (Iran Standard Time)

<script src="https://cdn.jsdelivr.net/npm/jdate.js"></script>
<script type="text/javascript">
  (function() 
    var date = new Date();
    console.log("Normal format: " + date.echo("Y/m/d"));
    console.log("Jalali format: " + date.echoFa("Y/m/d"));
  )();
</script>

【讨论】:

以上是关于如何在 JavaScript 中将公历日期更改为波斯日期?的主要内容,如果未能解决你的问题,请参考以下文章

如何在tableview中将JSON字符串更改为日期格式

如何在 SQL Select 语句中将文本字段更改为日期字段

如何在php中将用户选择的日期更改为服务器的当前星期日期?

如何在 sqlalchemy 查询中将日期时间更改为字符串? [复制]

如何在 Amazon Redshift 中将列从字符串更改为日期?

如何在 Node.js 中将字符串日期更改为时间戳?