在matlab中检查时间戳间隔

时间:2014-08-25 04:21:09

标签: matlab timestamp

我只是想知道是否有办法比较许多时间戳,看看是否有任何遗失。 目前我正在观看一年365天,每天读取48个读数。 (在excel文档中)因此我有超过17000点要分析。 目前,时间戳的格式为:

1/01/2011 12:30 AM
1/01/2011 1:00 AM
1/01/2011 1:30 AM
1/01/2011 2:00 AM
1/01/2011 2:30 AM

我需要经历并查看每30分钟是否缺少任何值。我想过用

datenum('')

然后尝试比较它,并在不遵循趋势时抛出错误并返回先前的值。但我不确定。

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:4)

您可以使用datenum并输入您提供的示例中的其中一个确切日期格式的字符串。如果你有半小时的时间间隔,那么连续datenum次调用之间的差异应该产生相同的差异。例如,让我们将您的日期放入一个单元格数组中,如下所示:

C = {'1/01/2011 12:30 AM',
'1/01/2011 1:00 AM',
'1/01/2011 1:30 AM',
'1/01/2011 2:00 AM',
'1/01/2011 2:30 AM'};

我们可以使用diff来区分连续元素。 diff如何工作,给定数组中的i th 元素,给定输入值y_i的{​​{1}}处的向量输出为:

x_i

因此,这将返回一个长度比原始长度小1的向量。我们基本上从你日期的第二个元素开始考虑元素。因此,对此单元格数组中的每个元素应用y_i = x_{i+1} - x_i diff,我们得到:

datenum

前7位有效数字左右重要。其余的数字是由于一些精确的差异,但我们现在搁置它。因此,您需要检查差异中的每个元素是否都是format long diffs = diff(datenum(C)) diffs = 0.020833333255723 0.020833333372138 0.020833333372138 0.020833333255723 。如果不是,那么你错过了一个间隔。让我们尝试捏几下:

0.0208333

因此,对于C = {'1/01/2011 12:30 AM', '1/01/2011 1:30 AM', '1/01/2011 2:30 AM', '1/01/2011 3:00 AM', '1/01/2011 4:30 AM'}; format long diffs = diff(datenum(C)) diffs = 0.041666666627862 0.041666666627862 0.020833333372138 0.062500000000000 的第二,第三和最后一个元素,我们在半小时间隔内缺少测量值。具体来说,我假设你的单位是半小时。因此,缺失测量之间的最小可能跳跃是一小时,并且这是C0.0208之间的跳跃,因此关于0.0416的差异。因此,我们需要在此数组中找到大于0.02的位置。为安全起见,我们将其设置为0.0416。因此,如果您想以编程方式执行此操作,则可以执行此操作:

0.03

find计算满足特定布尔条件的矩阵/数组中的位置。在这种情况下,我们希望找到差异为diffs = diff(datenum(C)); locs = find(diffs > 0.03) + 1; 的位置。我们也偏移> 0.03,因为我们正在研究像之前谈到的第二个元素。通过修改后的1数组执行此操作,我们得到:

C

这告诉我们在修改日期数组(locs = 2 3 5 )的位置2,3和5处,我们在半小时标记处缺少测量结果。

要仔细检查我们的第一个例子,如果我们在没有跳过的第一个例子中应用了这个,我们按预期得到空数组:

C

作为一点奖励,我们可以显示缺少间隔的位置。具体做法是:

locs = 

[]

对于我们的捏造时间示例,我们得到:

missingTimes = C(locs)

修改

在评论中我们的谈话中,一旦你有一个没有时间和日期的约会,这就会搞砸。具体来说,当您在单元格数组中至少调用其中一个missingTimes = '1/01/2011 1:30 AM' '1/01/2011 2:30 AM' '1/01/2011 4:30 AM' 时,我们将不再获得浮点精度。我们只会得到整数(出于某种奇怪的原因......我无法弄清楚原因。我应该在这篇文章中写一篇StackOverflow文章)。换句话说,如果我们这样做:

datenum

如果我们这样做了:

C = {'1/01/2011',
'1/01/2011 12:30 AM',
'1/01/2011 1:30 AM',
'1/01/2011 2:30 AM',
'1/01/2011 3:00 AM',
'1/01/2011 4:30 AM'};

我们得到:

diff(datenum(C))

为了解决这个问题,我必须实现自己的ans = 0 0 0 0 0 版本,并分别访问日期数组中的元素。因此,请改为:

diff

我使用arrayfun并指定了一个输入数组,该数组从2到format long; diffs = arrayfun(@(x) datenum(C{x}) - datenum(C{x-1}), (2:numel(C)).'); 中的元素数量。对于输出中的每个元素,我们采用C元素的datenum表示,并从i+1元素中减去它。这基本上是手动实现i操作,当你包含一个没有时间的日期时,它会逃避轻微的错误。老实说,我不知道为什么整个数字之后的所有小数点都被删除了....但是现在这个有效。

无论如何,我们得到:

diff

编辑#2

看起来你仍然遇到麻烦。我要做的另一个建议是找到那些缺少 diffs = 0.020833333372138 0.041666666627862 0.041666666627862 0.020833333372138 0.062500000000000 时间戳的时间。然后我们会找到这些条目并手动放置12:00 AM时间戳。因此,我们可以使用正则表达式通过regexp来执行此操作。正则表达式尝试查找字符串中出现模式的位置。因此,我们要做的就是找到那些最终包含时间戳的模式,然后使用一些额外的代码来插入此时间戳。让&# 39;考虑一个玩具的例子:

12:00 AM

这里我们有各种日期和时间,有些人遗漏了C = {'1/01/2011', '1/01/2011 12:30 AM', '1/01/2011 1:30 AM', '1/01/2011 2:30 AM', '1/01/2011 3:00 AM', '1/01/2011 4:30 AM', '1/02/2011', '1/02/2011 12:30 AM', '1/02/2011 1:30 AM', '1/02/2011 2:30 AM', '1/02/2011 3:00 AM', '1/02/2011 4:30 AM', '1/03/2011', '1/03/2011 12:30 AM', '1/03/2011 1:30 AM', '1/03/2011 2:30 AM', '1/03/2011 3:00 AM', '1/03/2011 4:30 AM'}; 时间戳。因此,以下是我将如何插入时间戳:

12:00 AM

这看起来像一些令人生畏的代码,但肯定可以解释。让我们从第一行代码开始。首先,我们调用missingTimeStampsLocs = cellfun(@(x) isempty(regexp(x,'[0-9]{1,2}\/[0-9]{2}\/[0-9]{4} [0-9]{1,2}:[0-9]{2} [AaPp][Mm]')), C); missingTimeStamps = C(missingTimeStampsLocs); filledInTimeStamps = cellfun(@(x) [x ' 12:00 AM'], missingTimeStamps, 'uni', 0); C(missingTimeStampsLocs) = filledInTimeStamps; ,其中包含我们想要查看的字符串,然后第二个参数用于描述您正在寻找的模式。我在这里要做的是,我将按照以下格式查找所有日期:

regexp

#/##/#### ##:## xx OR ##/##/#### ##:## xx 表示一个数字,#表示一个字符。我们将搜索遵循此完全格式的所有日期。任何不遵循此格式的日期我们都会标记,这意味着它们缺少时间戳。看一下这句话:

x

这就是说,对于字符串regexp(x,'[0-9]{1,2}\/[0-9]{2}\/[0-9]{4} [0-9]{1,2}:[0-9]{2} [AaPp][Mm]') ,我们将查找以1或2个数字开头的字符串,后跟x,后跟正好2个数字,然后是通过/,后跟4个数字,后跟一个空格,然后我们将查找1或2个数字,然后是/,然后是2个数字,后跟一个空格,然后:AM不区分大小写。这意味着PMAM可以是大写或小写。

PM返回的内容是字符串中找到此字符串的位置。在我们的情况下,它会返回regexp,意味着我们在开始处找到了这个字符串,或者为空,这意味着我们还没有找到这样的字符串一个字符串。如果1返回空,则此日期缺少时间戳。这就是我用isempty打包此调用以检查regexp是否返回空的原因。然后我使用cellfun包装此调用,以便我们可以遍历日期单元格数组中的所有元素。输出(存储在regexp中)将包含一个布尔数组,其中missingTimeStampsLocs表示缺少时间戳,1表示它不会丢失。

下一行代码然后从原始单元格数据中提取那些缺少日期的日期。然后我再次运行0来迭代这些单元格,然后我们在这个提取的单元格数组中连接每个字符串末尾的cellfun时间戳。请注意,我还指定了两个附加参数(12:00 AM'uni'),因为输出不再是单个值,而是字符串。这些字符串将被放置在单元格数组中,这是完美的,因为无论如何它们都是从单元格数组中提取的。我们没有必要在第一个0调用中指定此项,因为输出是单个值 - 在这种情况下,它是布尔值cellfun0。完成后,我们将那些缺少时间戳的日期替换为我们刚填入1时间戳的日期。这会被覆盖到12:00 AM。因此,通过使用我们的C运行上述代码,这就是我们得到的:

C

然后我们可以通过检测代码运行它,看看哪些日期跳了半个小时。

C =  

'1/01/2011 12:00 AM'
'1/01/2011 12:30 AM'
'1/01/2011 1:30 AM'
'1/01/2011 2:30 AM'
'1/01/2011 3:00 AM'
'1/01/2011 4:30 AM'
'1/02/2011 12:00 AM'
'1/02/2011 12:30 AM'
'1/02/2011 1:30 AM'
'1/02/2011 2:30 AM'
'1/02/2011 3:00 AM'
'1/02/2011 4:30 AM'
'1/03/2011 12:00 AM'
'1/03/2011 12:30 AM'
'1/03/2011 1:30 AM'
'1/03/2011 2:30 AM'
'1/03/2011 3:00 AM'
'1/03/2011 4:30 AM'

我们得到:

diffs = diff(datenum(C));
locs = find(diffs > 0.03) + 1;
missingTimes = C(locs)

我真的希望这是我最后一次解决这个问题(LOL),因为我非常确定我已经涵盖了所有意外情况。我还假设您的日期是以特定方式格式化的,我希望这可以解决您的问题。我们也不需要使用我们编写的自定义missingTimes = '1/01/2011 1:30 AM' '1/01/2011 2:30 AM' '1/01/2011 4:30 AM' '1/02/2011 12:00 AM' '1/02/2011 1:30 AM' '1/02/2011 2:30 AM' '1/02/2011 4:30 AM' '1/03/2011 12:00 AM' '1/03/2011 1:30 AM' '1/03/2011 2:30 AM' '1/03/2011 4:30 AM' 函数,因为我现在正在完成日期以获得diff时间戳。

祝你好运!