简体   繁体   English

从一系列对象中获取本月的第一天

[英]Get the first day of this month from an array of objects

If today is 2018-11-28, I have an array of object like that: 如果今天是2018-11-28,我有一个类似这样的对象数组:

  const dataset = [
  {
    "timestamp": "2018-11-28T16:38:07.610Z",
    "value": 751.998557581834
  },
  {
    "timestamp": "2018-11-27T16:38:07.610Z",
    "value": 644.9987628195244
  },
  {
    "timestamp": "2018-11-26T16:38:07.610Z",
    "value": 766.9985288101943
  },
  {
    "timestamp": "2018-11-25T16:38:07.610Z",
    "value": 953.9981701237627
  },
  {
    "timestamp": "2018-11-24T16:38:07.610Z",
    "value": 912.9982487662423
  },
  {
    "timestamp": "2018-11-23T16:38:07.610Z",
    "value": 402
  },
  {
    "timestamp": "2018-11-22T16:38:07.610Z",
    "value": 914.9982449300243
  },
  {
    "timestamp": "2018-11-21T16:38:07.610Z",
    "value": 769.9985230558668
  },
  {
    "timestamp": "2018-11-20T16:38:07.610Z",
    "value": 772.9985173015398
  },
  {
    "timestamp": "2018-11-19T16:38:07.610Z",
    "value": 176
  },
  {
    "timestamp": "2018-11-18T16:38:07.610Z",
    "value": 978.9981221710306
  },
  {
    "timestamp": "2018-11-17T16:38:07.611Z",
    "value": 342
  },
  {
    "timestamp": "2018-11-16T16:38:07.611Z",
    "value": 498.9990428634777
  },
  {
    "timestamp": "2018-11-15T16:38:07.611Z",
    "value": 326
  },
  {
    "timestamp": "2018-11-14T16:38:07.612Z",
    "value": 649.9987532289786
  },
  {
    "timestamp": "2018-11-13T16:38:07.612Z",
    "value": 70
  },
  {
    "timestamp": "2018-11-12T16:38:07.612Z",
    "value": 349
  },
  {
    "timestamp": "2018-11-11T16:38:07.612Z",
    "value": 191
  },
  {
    "timestamp": "2018-11-10T16:38:07.612Z",
    "value": 154
  },
  {
    "timestamp": "2018-11-09T16:38:07.613Z",
    "value": 109
  },
  {
    "timestamp": "2018-11-08T16:38:07.613Z",
    "value": 237
  },
  {
    "timestamp": "2018-11-07T16:38:07.613Z",
    "value": 398
  },
  {
    "timestamp": "2018-11-06T16:38:07.613Z",
    "value": 606.9988357076774
  },
  {
    "timestamp": "2018-11-05T16:38:07.614Z",
    "value": 131
  },
  {
    "timestamp": "2018-11-04T16:38:07.614Z",
    "value": 397
  },
  {
    "timestamp": "2018-11-03T16:38:07.614Z",
    "value": 583.9988798241893
  },
  {
    "timestamp": "2018-11-02T16:38:07.614Z",
    "value": 362
  },
  {
    "timestamp": "2018-11-01T16:38:07.614Z",
    "value": 686.998682258936
  },
  {
    "timestamp": "2018-10-31T16:38:07.614Z",
    "value": 131
  },
  {
    "timestamp": "2018-10-30T16:38:07.614Z",
    "value": 212
  }
]

The objects are created using this code: 使用以下代码创建对象:

  import { DateTime } from 'luxon'

  const timestamp = startDate.minus({ days: i }).toJSDate()
  return { timestamp: timestamp, value: randomValue }

I want the object containing the first day of this month so, in this example, I want: 我想要包含本月第一天的对象,因此,在此示例中,我想要:

  {
    "timestamp": "2018-11-01T16:38:07.614Z",
    "value": 686.998682258936
  }

This is what I tried: 这是我尝试的:

const date = new Date()
const firstDayOfThisMonth = new Date(date.getFullYear(), date.getMonth(), 1)
const firstDayOfThisMonthSub = firstDayOfThisMonth.toString().substring(0, 15)
const bo = dataset.map((d, i) => {
  const sub = d.toString().substring(0, 15)
  if (sub === firstDayOfThisMonthSub) return d
})

It doesn't work (I get an array of undefined ) and I hope there is a smarter way to do that. 它不起作用(我得到了undefined数组),我希望有一种更聪明的方法来做到这一点。 I can use Javascript Date object or Luxon library. 我可以使用Javascript Date对象或Luxon库。

Thanks 谢谢

With luxon : 使用luxon:

const firstDayOfThisMonth = DateTime.local().startOf('month')
const firstDayRecord = dataset.find(record => {
 return DateTime.fromISO(record.timestamp).hasSame(firstDayOfThisMonth, 'day')
})

This should do the trick 这应该可以解决问题

You have UTC timestamps but it's not clear to me if you want the local first day of the month or UTC first day of the month. 您具有UTC时间戳,但是我不清楚您想要本地的第一天还是UTC的第一天。 If you want UTC, getting the first day of the month as an ISO 8601 date can be simplified to: 如果需要UTC,则可以将每月的第一天作为ISO 8601日期简化为:

let date = new Date().toISOString().slice(0,8) + '01';

Noting that the UTC month will be different to the local month for the period of the host timezone offset at the start or end of the month depending on whether it's east or west of Greenwich respectively. 请注意,在当地时区的UTC月份在月初或月末偏移时,UTC月份将与当地月份不同,这分别取决于它在格林威治的东边还是西边。 You can then use filter to get matching elements, Eg 然后,您可以使用过滤器获取匹配的元素,例如

 var data = [{"timestamp": "2018-11-02T16:38:07.614Z","value": 362}, {"timestamp": "2018-11-01T16:38:07.614Z","value": 686.998}, {"timestamp": "2018-10-31T16:38:07.614Z","value": 131}, {"timestamp": "2018-10-30T16:38:07.614Z","value": 212}]; var s = new Date().toISOString().slice(0,8) + '01'; var d = data.filter(o => o.timestamp.slice(0,10) == s); console.log(d); 

However, if you want to find the timestamp for the local first day of the month, you should convert the timestamps to Dates and compare with the start and end of the local first day of the month, eg 但是,如果要查找本月本地第一天的时间戳,则应将时间戳转换为日期,并与本月本地第一天的开始和结束进行比较。

 var data = [{"timestamp": "2018-11-02T16:38:07.614Z","value": 362}, {"timestamp": "2018-11-01T16:38:07.614Z","value": 686.998}, {"timestamp": "2018-10-31T16:38:07.614Z","value": 131}, {"timestamp": "2018-10-30T16:38:07.614Z","value": 212}]; var d = new Date(); d.setDate(1); let firstOfMonthStart = d.setHours(0,0,0,0); let firstOfMonthEnd = d.setHours(23,59,59,999); let t = data.filter(o => { let d = new Date(o.timestamp); return d >= firstOfMonthStart && d <= firstOfMonthEnd; }); console.log(t); 

Note that firstOfMonthStart and firstOfMonthEnd will be time values, not Dates, but the comparison works because < and > coerce the values to number, so the comparison works exactly as if they were Dates. 请注意, firstOfMonthStartfirstOfMonthEnd将是时间值,而不是日期,但是比较有效,因为<>将值强制转换为数字,因此比较的工作方式就好像它们是日期一样。

For someone whose local timezone is, say, +10:00, the returned array in November 2018 is: 对于本地时区为+10:00的用户,2018年11月返回的数组为:

[{timestamp: "2018-10-31T16:38:07.614Z", value: 131}]

since their local start of month is 2018-10-31T14:00:00Z. 因为他们的本地月开始时间是2018-10-31T14:00:00Z。

map() isn't the right tool. map()不是正确的工具。 It will give you a value for every item in the original array, even if it's undefined . 即使它是undefined ,它也会为您提供原始数组中每个项目的值。 To get a subset of an array, use filter() . 要获取数组的子集,请使用filter()

Since these are nice ISO 8601 date strings. 由于这些都是不错的ISO 8601日期字符串。 You can build a datestring like '2018-11-01' and filter based on wether the dat starts with it: 您可以构建日期字符串(例如“ 2018-11-01”),并根据数据以其开头的日期进行过滤:

 let a = [ {"timestamp": "2018-11-28T16:38:07.610Z","value": 751.998557581834},{"timestamp": "2018-11-27T16:38:07.610Z","value": 644.9987628195244},{"timestamp": "2018-11-26T16:38:07.610Z","value": 766.9985288101943},{"timestamp": "2018-11-25T16:38:07.610Z","value": 953.9981701237627},{"timestamp": "2018-11-24T16:38:07.610Z","value": 912.9982487662423},{"timestamp": "2018-11-23T16:38:07.610Z","value": 402},{"timestamp": "2018-11-22T16:38:07.610Z","value": 914.9982449300243},{"timestamp": "2018-11-21T16:38:07.610Z","value": 769.9985230558668},{"timestamp": "2018-11-20T16:38:07.610Z","value": 772.9985173015398},{"timestamp": "2018-11-19T16:38:07.610Z","value": 176},{"timestamp": "2018-11-18T16:38:07.610Z","value": 978.9981221710306},{"timestamp": "2018-11-17T16:38:07.611Z","value": 342},{"timestamp": "2018-11-16T16:38:07.611Z","value": 498.9990428634777},{"timestamp": "2018-11-15T16:38:07.611Z","value": 326},{"timestamp": "2018-11-14T16:38:07.612Z","value": 649.9987532289786},{"timestamp": "2018-11-13T16:38:07.612Z","value": 70},{"timestamp": "2018-11-12T16:38:07.612Z","value": 349},{"timestamp": "2018-11-11T16:38:07.612Z","value": 191},{"timestamp": "2018-11-10T16:38:07.612Z","value": 154},{"timestamp": "2018-11-09T16:38:07.613Z","value": 109},{"timestamp": "2018-11-08T16:38:07.613Z","value": 237},{"timestamp": "2018-11-07T16:38:07.613Z","value": 398},{"timestamp": "2018-11-06T16:38:07.613Z","value": 606.9988357076774},{"timestamp": "2018-11-05T16:38:07.614Z","value": 131},{"timestamp": "2018-11-04T16:38:07.614Z","value": 397},{"timestamp": "2018-11-03T16:38:07.614Z","value": 583.9988798241893},{"timestamp": "2018-11-02T16:38:07.614Z","value": 362},{"timestamp": "2018-11-01T16:38:07.614Z","value": 686.998682258936},{"timestamp": "2018-10-31T16:38:07.614Z","value": 131},{"timestamp": "2018-10-30T16:38:07.614Z","value": 212}] let now = new Date() // start of month is always 01 // month is zero indexed let pattern = `${now.getUTCFullYear()}-${now.getUTCMonth()+1}-01` let filtered = a.filter(item => item.timestamp.startsWith(pattern)) console.log(filtered) 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM