如何使用JavaScript中的时区检查打开到关闭时间是否已过去 [英] How to check if open to close time has elapse using timezone in javascript

查看:77
本文介绍了如何使用JavaScript中的时区检查打开到关闭时间是否已过去的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的Web应用程序中具有以下功能,以检查从 OPEN CLOSE 的时间是否已使用国家/地区时区而且工作正常。我正在尝试优化我的网站,所以我的问题是如何在不使用时区时区的情况下在javascript中创建类似这样的函数?时区文件很大,这是它在我的网站上的唯一用法。



  function isOpen(openTime,closeTime,timezone){//处理特殊情况,如果(openTime === 24HR){返回打开; } //获取给定时区中的当前日期和时间const now = moment.tz(timezone); //获取给定时区中该日期的确切打开和关闭时间const date = now.format( YYYY-MM-DD); const storeOpenTime = moment.tz(date +‘’+ openTime, YYYY-MM-DD h:mmA,时区); const storeCloseTime = moment.tz(date +’’+ closeTime, YYYY-MM-DD h:mmA,时区);让我们检查一下; if(storeCloseTime.isBefore(storeOpenTime)){//处理跨越午夜的范围check = now.isAfter(storeOpenTime)|| now.isBefore(storeCloseTime); } else {//使用包含开始时间和包含结束时间的正常范围检查= now.isBetween(storeOpenTime,storeCloseTime,null,‘[)’); }退票? 打开关闭; } const zone = Asia / Kuala_Lumpur; console.log( 24HR,isOpen( 24HR,undefined,zone)); console.log( 2:00 AM-8:00AM,isOpen( 2:00 AM , 8:00 AM,zone)); console.log( 8:00 AM-10:00AM,isOpen( 8:00 AM, 10:00 PM,zone));  

 < script src = https://cdnjs.cloudflare.com/ajax/ libs / moment.js / 2.24.0 / moment.min.js>< / script>< script src = https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.27 /moment-timezone-with-data-10-year-range.min.js\"></script>  

p>

解决方案

您可以使用 Intl.DateTimeFormat 构造函数可以完成相同的操作。据我了解,您想知道一家营业时间为8:00至12:00的商店(例如Asia / Kuala_Lumpur)目前正在营业。



可能是可以或多或少地逐行转换代码,但是我刚刚对其进行了重构,并简化了逻辑(我懒说……)。这样,它可以将当前时间获取到所需的位置,将其转​​换为午夜以来的分钟数,然后查看该时间是在开始时间之前还是在结束时间之前或之后。



对于午夜(12:00 AM),时间转换为0分钟,因此,如果 closingTime 为0,则假定为一天结束,因此将其设置为1,440(即,一天结束时的午夜)。



测试时间仅在同一天工作,如果开放时间超过午夜,则需要对其进行重构。我刚刚测试了午夜至中午和中午至午夜,所以一个应该始终显示打开,另一个始终显示关闭。



您也可以考虑使用Luxon,它会执行moment.js + moment.tz的操作,但是使用Intl对象而不是包含的数据。



编辑



要处理超过午夜的时间,您可以在时间中包括日期(如果要使用常规的日程安排则不方便),也可以进行内部和外部测试,以便在关闭时间为在开放时间之前,您测试开放时间与关闭时间之间的时间是否是 not 。可以通过比较openMin和关闭时间并调整测试来完成。



这不会处理重叠的开始时间和结束时间,但实际上不适合常规每日计划(尽管它可能适合每周或更长时间的计划)。



  / * @param {string}位置:IANA代表位置** @param {Date}日期:获取时间的日期实例,默认为现在** @以h:mm ap格式返回@string}时间* / function getTime (位置,日期=新的Date()){返回date.toLocaleString('en',{timeZone:位置,小时:数字,分钟: 2位数,dayPeriod:短});} / * @param {string}时间:h:mm A ** @returns {number}时间转换为分钟* /函数timeToMin(time){let [h,m] = time.match(/ \d\d?/ G); h = h%12; if(/pm$/i.test(time))h + = 12 return h * 60 + parseInt(m);} / * @param {string} openTime:打开时间,以h:mm ap格式** @param { string} closeTime:以h:mm ap格式关闭的时间** @param {string}位置:IANA代表位置** @return {string}如果当前时间在openTime和closeTime所在位置之内,则打开,**否则关闭* /功能isOpen(openTime,closeTime,location){如果(openTime =='24HR')返回'open';让nowTime = getTime(location);让nowMin = timeToMin(nowTime);让openMin = timeToMin(openTime);让closeMin = timeToMin(closeTime)|| 1440; //如果(openMin< closeMin){return nowMin< openMin || nowMin> = closeMin? 关闭:打开; //打开后第二天关闭} else {return nowMin> = openMin&& nowMin< closeMin? '打开关闭'; }} // KLlet中的时间loc = Asia / Kuala_Lumpur; console.log(ʻ$ {loc}中的$ {getTime(loc)}`)); //示例[[ 24HR,未定义,loc], //打开24小时[ 12:00 AM, 12:00 PM,loc],//午夜至中午[ 12:00 PM, 12:00 AM,loc],//中午至午夜[ 6 :30PM, 04:00 AM,loc],//午夜] .forEach(args => console.log(`$ {args [0]} $ {args [1]?'-'+ args [ 1]:''} $ {isOpen(... args)}`)));  


I have this below functionin my webapp to check if from OPEN to CLOSE time has elapse using a country timezone and it's working fine. Am trying to optimize my website, so my question is how can i make a function like this in javascript without the use of moment timezone? The moment timezone file is large and this is the only usage of it on my website.

    function isOpen(openTime, closeTime, timezone) {
    
      // handle special case
      if (openTime === "24HR") {
        return "open";
      }
    
      // get the current date and time in the given time zone
      const now = moment.tz(timezone);
    
      // Get the exact open and close times on that date in the given time zone
      const date = now.format("YYYY-MM-DD");
      const storeOpenTime = moment.tz(date + ' ' + openTime, "YYYY-MM-DD h:mmA", timezone);
      const storeCloseTime = moment.tz(date + ' ' + closeTime, "YYYY-MM-DD h:mmA", timezone);
    
      let check;
      if (storeCloseTime.isBefore(storeOpenTime)) {
        // Handle ranges that span over midnight
        check = now.isAfter(storeOpenTime) || now.isBefore(storeCloseTime);
      } else {
        // Normal range check using an inclusive start time and exclusive end time
        check = now.isBetween(storeOpenTime, storeCloseTime, null, '[)');
      }
    
      return check ? "open" : "closed";
    }
    
const zone = "Asia/Kuala_Lumpur";
console.log("24HR", isOpen("24HR", undefined, zone));
console.log("2:00AM-8:00AM", isOpen("2:00AM", "8:00AM", zone));
console.log("8:00AM-10:00AM", isOpen("8:00AM", "10:00PM", zone));

<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.27/moment-timezone-with-data-10-year-range.min.js"></script>

解决方案

You can use the Intl.DateTimeFormat constructor to do the same thing. As I understand it, you want to know if a store that is open say from 8:00 to 12:00 in say Asia/Kuala_Lumpur is currently open.

It's probably possible to convert your code more or less line by line, but I've just refactored it and simplified the logic (call me lazy…). This way it gets the current time in the desired location, converts it to minutes since midnight, then sees if that is before the start time or on or after the closing time.

For midnight (12:00 AM), the time converts to 0 minutes so if closingTime is 0, it's assumed to be end of day so is set to 1,440 (i.e. midnight at end of day).

The test times only work on the same day, if the open time runs over midnight you'll need to refactor it. I've just tested midnight to noon and noon to midnight so one should always show "open" and the other "closed".

You might also consider using Luxon, it does what moment.js + moment.tz does but uses the Intl object instead of included data.

Edit

To deal with times that go over midnight, you can either include dates in the time (not convenient if you want to use a regular daily schedule) or you can have an "inside" and "outside" test so that if closing time is before the open time, you test if the time is not between open and close times. That can be done by comparing openMin and close times and adjusting the test.

This will not deal with overlapping start and end times, but that doesn't really fit a regular daily schedule (though it might fit a weekly or longer schedule).

/* @param {string} location: IANA representative location
** @param {Date} date: date instance to get time from, default is now
** @returns {string} time in location in h:mm ap format
*/
function getTime(location, date = new Date()) {
  return date.toLocaleString('en', {
    timeZone: location,
    hour  :  'numeric',
    minute: '2-digit',
    dayPeriod: 'short'
  });
}

/* @param {string} time: h:mm A
** @returns {number} time converted to minutes
*/
function timeToMin(time) {
  let [h, m] = time.match(/\d\d?/g);
  h = h%12;
  if (/pm$/i.test(time)) h +=12
  return h * 60 + parseInt(m);
}

/* @param {string} openTime: opening time in h:mm ap format
** @param {string} closeTime: closing time in h:mm ap format
** @param {string} location: IANA representative location
** @return {string} open if current time is within openTime and closeTime in location,
**                  closed otherwise
*/
function isOpen(openTime, closeTime, location) {
  if (openTime == '24HR') return 'open';
  let nowTime = getTime(location);
  let nowMin = timeToMin(nowTime);
  let openMin = timeToMin(openTime);
  let closeMin = timeToMin(closeTime) || 1440;
  // Open and close on same day
  if (openMin < closeMin) {
    return nowMin < openMin || nowMin >= closeMin ? 'closed' : 'open';
  // Close on day after open
  } else {
    return nowMin >= openMin && nowMin < closeMin ? 'open' : 'closed';
  }
}

// Time in KL
let loc = "Asia/Kuala_Lumpur";
console.log(`In ${loc} it's ${getTime(loc)}`);

// Examples
[["24HR", undefined, loc],     // Open 24 hrs
 ["12:00AM", "12:00PM", loc],  // Midnight to noon
 ["12:00PM", "12:00AM", loc],  // Noon to midnight
 ["6:30PM",  "04:00AM", loc],  // Over midnight
].forEach(args => console.log(
  `${args[0]}${args[1]? '-' + args[1] : ''} ${isOpen(...args)}`
));

这篇关于如何使用JavaScript中的时区检查打开到关闭时间是否已过去的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆