Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 64FCD200C3A for ; Fri, 17 Mar 2017 01:37:15 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 6398B160B8B; Fri, 17 Mar 2017 00:37:15 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 7FF1A160B78 for ; Fri, 17 Mar 2017 01:37:14 +0100 (CET) Received: (qmail 4852 invoked by uid 500); 17 Mar 2017 00:37:13 -0000 Mailing-List: contact commits-help@metron.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@metron.incubator.apache.org Delivered-To: mailing list commits@metron.incubator.apache.org Received: (qmail 4843 invoked by uid 99); 17 Mar 2017 00:37:13 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd4-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 17 Mar 2017 00:37:13 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd4-us-west.apache.org (ASF Mail Server at spamd4-us-west.apache.org) with ESMTP id 44CF3C0FD6 for ; Fri, 17 Mar 2017 00:37:13 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd4-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -3.069 X-Spam-Level: X-Spam-Status: No, score=-3.069 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_NUMSUBJECT=0.5, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-0.001, SPF_NEUTRAL=0.652] autolearn=disabled Received: from mx1-lw-us.apache.org ([10.40.0.8]) by localhost (spamd4-us-west.apache.org [10.40.0.11]) (amavisd-new, port 10024) with ESMTP id rXF6-hCjHMns for ; Fri, 17 Mar 2017 00:37:11 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx1-lw-us.apache.org (ASF Mail Server at mx1-lw-us.apache.org) with SMTP id 71FF360E08 for ; Fri, 17 Mar 2017 00:37:10 +0000 (UTC) Received: (qmail 4840 invoked by uid 99); 17 Mar 2017 00:37:09 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 17 Mar 2017 00:37:09 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 962BDDFDC5; Fri, 17 Mar 2017 00:37:09 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: mattf@apache.org To: commits@metron.incubator.apache.org Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: incubator-metron git commit: METRON-764 DST bug in metron-profiler-client Unit Tests (mattf-horton) closes apache/incubator-metron#476 Date: Fri, 17 Mar 2017 00:37:09 +0000 (UTC) archived-at: Fri, 17 Mar 2017 00:37:15 -0000 Repository: incubator-metron Updated Branches: refs/heads/master 68a334a87 -> f1435a6a7 METRON-764 DST bug in metron-profiler-client Unit Tests (mattf-horton) closes apache/incubator-metron#476 Project: http://git-wip-us.apache.org/repos/asf/incubator-metron/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-metron/commit/f1435a6a Tree: http://git-wip-us.apache.org/repos/asf/incubator-metron/tree/f1435a6a Diff: http://git-wip-us.apache.org/repos/asf/incubator-metron/diff/f1435a6a Branch: refs/heads/master Commit: f1435a6a75f016294920ac328ba79474fbf129e1 Parents: 68a334a Author: mattf-horton Authored: Thu Mar 16 17:14:52 2017 -0700 Committer: YOUR NAME as In Apache Committed: Thu Mar 16 17:14:52 2017 -0700 ---------------------------------------------------------------------- .../metron-profiler-client/README.md | 29 ++++++++++++++++++++ .../client/window/WindowProcessorTest.java | 13 +++++++++ 2 files changed, 42 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/f1435a6a/metron-analytics/metron-profiler-client/README.md ---------------------------------------------------------------------- diff --git a/metron-analytics/metron-profiler-client/README.md b/metron-analytics/metron-profiler-client/README.md index 656bb25..aa35136 100644 --- a/metron-analytics/metron-profiler-client/README.md +++ b/metron-analytics/metron-profiler-client/README.md @@ -253,6 +253,35 @@ The specifiers are a set of fixed specifiers available as part of the language: * Countries supported are those supported in [jollyday](https://github.com/svendiedrichsen/jollyday/tree/master/src/main/resources/holidays) * Example: `holiday:us:nyc` would be the holidays of New York City, USA * Example: `holiday:hu` would be the holidays of Hungary + +**WARNING: Daylight Savings Time effects** + +While Universal Time (UTC) is nice and constant, many servers are set to local timezones that enable Daylight Savings Time (DST). +This means that twice a year, on DST transition weekends, "Sunday" is either 23 or 25 hours long. However, durations specified +as "7 days ago" are always interpreted as "7*24 hours ago". This can lead to some surprising effects when using days of the week +as inclusion or exclusion specifiers. + +For example, the profile window specified by the phrase "30 minute window every 24 hours from 7 days ago" +will always have 7 thirty-minute intervals, and these will normally occur on 5 weekdays and 2 weekend days. +However, if you invoke this window at 12:15am any day during the week following the start of DST, you will get +these intervals (supposing you start early on a Wednesday morning): +``` +Tuesday 12:15am-12:45am (yesterday) +Monday 12:15am-12:45am +Saturday 11:15pm-11:45pm (skipped Sunday!) +Friday 11:15pm-11:45pm +Thursday 11:15pm-11:45pm +Wednesday 11:15pm-11:45pm +Tuesday 11:15pm-11:45pm +``` + +Sunday got skipped over because it was only 23 hours long; that is, there were 24 hours between Saturday 11:15pm and Monday 12:15am. +So if you specified "excluding weekends", you would get 6 days' intervals instead of the expected 5. There are multiple variations +on this theme. + +Remember that the underlying time is kept in UTC, so the data is always correct. It is only when attempting to interpret UTC as +local time, date, and day, that these confusions may occur. They may be eliminated by setting your server timezone to UTC, or otherwise +disabling DST. **Examples** http://git-wip-us.apache.org/repos/asf/incubator-metron/blob/f1435a6a/metron-analytics/metron-profiler-client/src/test/java/org/apache/metron/profiler/client/window/WindowProcessorTest.java ---------------------------------------------------------------------- diff --git a/metron-analytics/metron-profiler-client/src/test/java/org/apache/metron/profiler/client/window/WindowProcessorTest.java b/metron-analytics/metron-profiler-client/src/test/java/org/apache/metron/profiler/client/window/WindowProcessorTest.java index 94f9e04..79212e2 100644 --- a/metron-analytics/metron-profiler-client/src/test/java/org/apache/metron/profiler/client/window/WindowProcessorTest.java +++ b/metron-analytics/metron-profiler-client/src/test/java/org/apache/metron/profiler/client/window/WindowProcessorTest.java @@ -29,6 +29,13 @@ import java.util.Date; import java.util.List; import java.util.concurrent.TimeUnit; +/** + * On any test case where we explicitly include or exclude days of the week, in 24hr periods, + * we need to understand that on Daylight Savings Time (DST) transition weekends, + * Sunday is either 23 or 25 hours long. This leads to surprising correct results, + * that may fail the assert criteria, if one starts the hour before or after midnight. + * Thus in such test cases, we force now.setHours(6). + */ public class WindowProcessorTest { @Test @@ -129,6 +136,7 @@ public class WindowProcessorTest { Gotta be 2 tuesdays in 14 days. */ Date now = new Date(); + now.setHours(6); //avoid DST impacts if near Midnight List> intervals = w.toIntervals(now.getTime()); Assert.assertEquals(2, intervals.size()); } @@ -140,6 +148,7 @@ public class WindowProcessorTest { Gotta be 2 days with the same dow in 14 days. */ Date now = new Date(); + now.setHours(6); //avoid DST impacts if near Midnight List> intervals = w.toIntervals(now.getTime()); Assert.assertEquals(2, intervals.size()); } @@ -162,6 +171,7 @@ public class WindowProcessorTest { Window w = WindowProcessor.process("30 minute window every 24 hours from 7 days ago including saturdays excluding weekends"); Date now = new Date(); + now.setHours(6); //avoid DST impacts if near Midnight List> intervals = w.toIntervals(now.getTime()); Assert.assertEquals(0, intervals.size()); } @@ -171,6 +181,7 @@ public class WindowProcessorTest { Window w = WindowProcessor.process("30 minute window every 24 hours from 7 days ago excluding weekends"); Date now = new Date(); + now.setHours(6); //avoid DST impacts if near Midnight List> intervals = w.toIntervals(now.getTime()); Assert.assertEquals(5, intervals.size()); } @@ -198,6 +209,7 @@ public class WindowProcessorTest { Window w = WindowProcessor.process("1 hour window every 24 hours starting from 56 days ago including this day of the week"); Date now = new Date(); + now.setHours(6); //avoid DST impacts if near Midnight List> intervals = w.toIntervals(now.getTime()); Assert.assertEquals(8, intervals.size()); } @@ -208,6 +220,7 @@ public class WindowProcessorTest { Window w = WindowProcessor.process("30 minute window every 24 hours from 7 days ago excluding weekdays"); Date now = new Date(); + now.setHours(6); //avoid DST impacts if near Midnight List> intervals = w.toIntervals(now.getTime()); Assert.assertEquals(2, intervals.size()); }