{"action":"created","comment":{"url":"https://api.github.com/repos/rackerlabs/blueflood/pulls/comments/33200068","id":33200068,"diff_hunk":"@@ -0,0 +1,203 @@\n+/*\n+ * Copyright 2013 Rackspace\n+ *\n+ *    Licensed under the Apache License, Version 2.0 (the \"License\");\n+ *    you may not use this file except in compliance with the License.\n+ *    You may obtain a copy of the License at\n+ *\n+ *        http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ *    Unless required by applicable law or agreed to in writing, software\n+ *    distributed under the License is distributed on an \"AS IS\" BASIS,\n+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ *    See the License for the specific language governing permissions and\n+ *    limitations under the License.\n+ */\n+\n+package com.rackspacecloud.blueflood.utils;\n+\n+import org.apache.commons.lang.StringUtils;\n+import org.joda.time.DateTime;\n+import org.joda.time.format.DateTimeFormat;\n+\n+import java.util.Arrays;\n+import java.util.List;\n+import java.util.regex.Matcher;\n+import java.util.regex.Pattern;\n+\n+public class DateTimeParser {\n+    public static DateTime parse(String dateTimeOffsetString) {\n+        String stringToParse = dateTimeOffsetString.replace(\" \", \"\").replace(\",\", \"\").replace(\"_\", \"\");\n+\n+        if (StringUtils.isNumeric(stringToParse) && !isLikelyDateTime(stringToParse))\n+            return dateTimeFromTimestamp(stringToParse);\n+\n+        DateTime dateTime = tryParseDateTime(\"HH:mmyyyyMMdd\", stringToParse);\n+        if (dateTime != null)\n+            return dateTime;\n+\n+        List<String> splitList = splitDateTimeAndOffset(stringToParse);\n+        String offset = splitList.get(1);\n+        String dateTimeString = splitList.get(0);\n+\n+        DateTimeOffsetParser parser = new DateTimeOffsetParser(dateTimeString, offset);\n+        return parser.updateDateTime(new DateTime());\n+    }\n+\n+    private static class DateTimeOffsetParser {\n+        private String dateTime = \"\";\n+        private String offset = \"\";\n+\n+        public DateTimeOffsetParser(String dateTimeString, String offsetString) {\n+            this.dateTime = dateTimeString;\n+            this.offset = offsetString;\n+        }\n+\n+        public DateTime updateDateTime(DateTime baseDateTime) {\n+            baseDateTime = extractAndUpdateTime(baseDateTime);\n+            baseDateTime = extractAndUpdateDate(baseDateTime);\n+            if (!offset.equals(\"\"))\n+                baseDateTime = updateDateTimeWithOffset(baseDateTime);\n+            return baseDateTime;\n+        }\n+\n+        private DateTime updateDateTimeWithOffset(DateTime baseDateTime) {\n+            if (offset.equals(\"\"))\n+                return baseDateTime;\n+            Pattern p = Pattern.compile(\"(-?\\\\d*)([a-z]*)\");\n+            Matcher m = p.matcher(offset);\n+            if (!m.matches())\n+                return baseDateTime;\n+\n+            int count = Integer.parseInt(m.group(1));\n+            String unit = m.group(2);\n+\n+            DateTime dateTimeWithOffset = baseDateTime;\n+            if (unit.startsWith(\"s\"))\n+                dateTimeWithOffset = baseDateTime.plusSeconds(count);\n+            else if (unit.startsWith(\"min\"))\n+                dateTimeWithOffset = baseDateTime.plusMinutes(count);\n+            else if (unit.startsWith(\"h\"))\n+                dateTimeWithOffset = baseDateTime.plusHours(count);\n+            else if (unit.startsWith(\"d\"))\n+                dateTimeWithOffset = baseDateTime.plusDays(count);\n+            else if (unit.startsWith(\"mon\"))\n+                dateTimeWithOffset = baseDateTime.plusMonths(count);\n+            else if (unit.startsWith(\"y\"))\n+                dateTimeWithOffset = baseDateTime.plusYears(count);\n+\n+            return dateTimeWithOffset;\n+        }\n+\n+        private DateTime extractAndUpdateTime(DateTime inputDateTime) {\n+            DateTime resultDateTime = inputDateTime.withSecondOfMinute(0).withMillisOfSecond(0);\n+\n+            if (dateTime.equals(\"\") || dateTime.contains(\"now\"))\n+                return resultDateTime;\n+\n+            int hour = 0;\n+            int minute = 0;\n+            Pattern p = Pattern.compile(\"(\\\\d{1,2}):(\\\\d{2})([a|p]m)?(.*)\");\n+            Matcher m = p.matcher(dateTime);\n+            if (m.matches()) {\n+                hour = Integer.parseInt(m.group(1));\n+                minute = Integer.parseInt(m.group(2));\n+\n+                String middayModifier = m.group(3);\n+                if (middayModifier != null && middayModifier.equals(\"pm\"))\n+                    hour = (hour + 12) % 24;\n+\n+                dateTime = m.group(4);\n+            }\n+\n+            if (dateTime.contains(\"noon\")) {\n+                hour = 12;\n+                dateTime = dateTime.replace(\"noon\", \"\");\n+            }\n+            else if (dateTime.contains(\"teatime\")) {\n+                hour = 16;\n+                dateTime = dateTime.replace(\"teatime\", \"\");\n+            } else if (dateTime.contains(\"midnight\"))\n+                dateTime = dateTime.replace(\"midnight\", \"\");\n+\n+            return resultDateTime.withHourOfDay(hour).withMinuteOfHour(minute);\n+        }\n+\n+\n+        private DateTime extractAndUpdateDate(DateTime resultDateTime) {\n+            String stringToParse = this.dateTime;\n+\n+            if (stringToParse.contains(\"tomorrow\")) {\n+                resultDateTime = resultDateTime.plusDays(1);\n+                stringToParse = stringToParse.replace(\"tomorrow\", \"\");\n+            } else if (stringToParse.contains(\"yesterday\")) {\n+                resultDateTime = resultDateTime.minusDays(1);\n+                stringToParse = stringToParse.replace(\"yesterday\", \"\");\n+            } else if (stringToParse.contains(\"today\"))\n+                stringToParse = stringToParse.replace(\"today\", \"\");\n+\n+","path":"blueflood-http/src/main/java/com/rackspacecloud/blueflood/utils/DateTimeParser.java","position":139,"original_position":139,"commit_id":"2bb3567968b7f2ce4bfaadc2a753df2c2573a36a","original_commit_id":"2bb3567968b7f2ce4bfaadc2a753df2c2573a36a","user":{"login":"chinmay-gupte","id":4722931,"avatar_url":"https://avatars.githubusercontent.com/u/4722931?v=3","gravatar_id":"","url":"https://api.github.com/users/chinmay-gupte","html_url":"https://github.com/chinmay-gupte","followers_url":"https://api.github.com/users/chinmay-gupte/followers","following_url":"https://api.github.com/users/chinmay-gupte/following{/other_user}","gists_url":"https://api.github.com/users/chinmay-gupte/gists{/gist_id}","starred_url":"https://api.github.com/users/chinmay-gupte/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chinmay-gupte/subscriptions","organizations_url":"https://api.github.com/users/chinmay-gupte/orgs","repos_url":"https://api.github.com/users/chinmay-gupte/repos","events_url":"https://api.github.com/users/chinmay-gupte/events{/privacy}","received_events_url":"https://api.github.com/users/chinmay-gupte/received_events","type":"User","site_admin":false},"body":"NIT: extra new line.","created_at":"2015-06-24T21:40:07Z","updated_at":"2015-06-24T21:40:07Z","html_url":"https://github.com/rackerlabs/blueflood/pull/487#discussion_r33200068","pull_request_url":"https://api.github.com/repos/rackerlabs/blueflood/pulls/487","_links":{"self":{"href":"https://api.github.com/repos/rackerlabs/blueflood/pulls/comments/33200068"},"html":{"href":"https://github.com/rackerlabs/blueflood/pull/487#discussion_r33200068"},"pull_request":{"href":"https://api.github.com/repos/rackerlabs/blueflood/pulls/487"}}},"pull_request":{"url":"https://api.github.com/repos/rackerlabs/blueflood/pulls/487","id":38467225,"html_url":"https://github.com/rackerlabs/blueflood/pull/487","diff_url":"https://github.com/rackerlabs/blueflood/pull/487.diff","patch_url":"https://github.com/rackerlabs/blueflood/pull/487.patch","issue_url":"https://api.github.com/repos/rackerlabs/blueflood/issues/487","number":487,"state":"open","locked":false,"title":"Annotations: Pass 2","user":{"login":"chinmay-gupte","id":4722931,"avatar_url":"https://avatars.githubusercontent.com/u/4722931?v=3","gravatar_id":"","url":"https://api.github.com/users/chinmay-gupte","html_url":"https://github.com/chinmay-gupte","followers_url":"https://api.github.com/users/chinmay-gupte/followers","following_url":"https://api.github.com/users/chinmay-gupte/following{/other_user}","gists_url":"https://api.github.com/users/chinmay-gupte/gists{/gist_id}","starred_url":"https://api.github.com/users/chinmay-gupte/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chinmay-gupte/subscriptions","organizations_url":"https://api.github.com/users/chinmay-gupte/orgs","repos_url":"https://api.github.com/users/chinmay-gupte/repos","events_url":"https://api.github.com/users/chinmay-gupte/events{/privacy}","received_events_url":"https://api.github.com/users/chinmay-gupte/received_events","type":"User","site_admin":false},"body":"Reverts rackerlabs/blueflood#486","created_at":"2015-06-24T17:37:46Z","updated_at":"2015-06-24T21:40:07Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2ae209b1c5e0b84d2bd2f203609d32f942df2b86","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/rackerlabs/blueflood/pulls/487/commits","review_comments_url":"https://api.github.com/repos/rackerlabs/blueflood/pulls/487/comments","review_comment_url":"https://api.github.com/repos/rackerlabs/blueflood/pulls/comments{/number}","comments_url":"https://api.github.com/repos/rackerlabs/blueflood/issues/487/comments","statuses_url":"https://api.github.com/repos/rackerlabs/blueflood/statuses/2bb3567968b7f2ce4bfaadc2a753df2c2573a36a","head":{"label":"rackerlabs:revert-486-revert-480-annotations","ref":"revert-486-revert-480-annotations","sha":"2bb3567968b7f2ce4bfaadc2a753df2c2573a36a","user":{"login":"rackerlabs","id":84293,"avatar_url":"https://avatars.githubusercontent.com/u/84293?v=3","gravatar_id":"","url":"https://api.github.com/users/rackerlabs","html_url":"https://github.com/rackerlabs","followers_url":"https://api.github.com/users/rackerlabs/followers","following_url":"https://api.github.com/users/rackerlabs/following{/other_user}","gists_url":"https://api.github.com/users/rackerlabs/gists{/gist_id}","starred_url":"https://api.github.com/users/rackerlabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rackerlabs/subscriptions","organizations_url":"https://api.github.com/users/rackerlabs/orgs","repos_url":"https://api.github.com/users/rackerlabs/repos","events_url":"https://api.github.com/users/rackerlabs/events{/privacy}","received_events_url":"https://api.github.com/users/rackerlabs/received_events","type":"Organization","site_admin":false},"repo":{"id":10081109,"name":"blueflood","full_name":"rackerlabs/blueflood","owner":{"login":"rackerlabs","id":84293,"avatar_url":"https://avatars.githubusercontent.com/u/84293?v=3","gravatar_id":"","url":"https://api.github.com/users/rackerlabs","html_url":"https://github.com/rackerlabs","followers_url":"https://api.github.com/users/rackerlabs/followers","following_url":"https://api.github.com/users/rackerlabs/following{/other_user}","gists_url":"https://api.github.com/users/rackerlabs/gists{/gist_id}","starred_url":"https://api.github.com/users/rackerlabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rackerlabs/subscriptions","organizations_url":"https://api.github.com/users/rackerlabs/orgs","repos_url":"https://api.github.com/users/rackerlabs/repos","events_url":"https://api.github.com/users/rackerlabs/events{/privacy}","received_events_url":"https://api.github.com/users/rackerlabs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/rackerlabs/blueflood","description":"A distributed system designed to ingest and process time series data","fork":false,"url":"https://api.github.com/repos/rackerlabs/blueflood","forks_url":"https://api.github.com/repos/rackerlabs/blueflood/forks","keys_url":"https://api.github.com/repos/rackerlabs/blueflood/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rackerlabs/blueflood/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rackerlabs/blueflood/teams","hooks_url":"https://api.github.com/repos/rackerlabs/blueflood/hooks","issue_events_url":"https://api.github.com/repos/rackerlabs/blueflood/issues/events{/number}","events_url":"https://api.github.com/repos/rackerlabs/blueflood/events","assignees_url":"https://api.github.com/repos/rackerlabs/blueflood/assignees{/user}","branches_url":"https://api.github.com/repos/rackerlabs/blueflood/branches{/branch}","tags_url":"https://api.github.com/repos/rackerlabs/blueflood/tags","blobs_url":"https://api.github.com/repos/rackerlabs/blueflood/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rackerlabs/blueflood/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rackerlabs/blueflood/git/refs{/sha}","trees_url":"https://api.github.com/repos/rackerlabs/blueflood/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rackerlabs/blueflood/statuses/{sha}","languages_url":"https://api.github.com/repos/rackerlabs/blueflood/languages","stargazers_url":"https://api.github.com/repos/rackerlabs/blueflood/stargazers","contributors_url":"https://api.github.com/repos/rackerlabs/blueflood/contributors","subscribers_url":"https://api.github.com/repos/rackerlabs/blueflood/subscribers","subscription_url":"https://api.github.com/repos/rackerlabs/blueflood/subscription","commits_url":"https://api.github.com/repos/rackerlabs/blueflood/commits{/sha}","git_commits_url":"https://api.github.com/repos/rackerlabs/blueflood/git/commits{/sha}","comments_url":"https://api.github.com/repos/rackerlabs/blueflood/comments{/number}","issue_comment_url":"https://api.github.com/repos/rackerlabs/blueflood/issues/comments{/number}","contents_url":"https://api.github.com/repos/rackerlabs/blueflood/contents/{+path}","compare_url":"https://api.github.com/repos/rackerlabs/blueflood/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rackerlabs/blueflood/merges","archive_url":"https://api.github.com/repos/rackerlabs/blueflood/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rackerlabs/blueflood/downloads","issues_url":"https://api.github.com/repos/rackerlabs/blueflood/issues{/number}","pulls_url":"https://api.github.com/repos/rackerlabs/blueflood/pulls{/number}","milestones_url":"https://api.github.com/repos/rackerlabs/blueflood/milestones{/number}","notifications_url":"https://api.github.com/repos/rackerlabs/blueflood/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rackerlabs/blueflood/labels{/name}","releases_url":"https://api.github.com/repos/rackerlabs/blueflood/releases{/id}","created_at":"2013-05-15T14:50:39Z","updated_at":"2015-06-24T20:11:12Z","pushed_at":"2015-06-24T20:23:09Z","git_url":"git://github.com/rackerlabs/blueflood.git","ssh_url":"git@github.com:rackerlabs/blueflood.git","clone_url":"https://github.com/rackerlabs/blueflood.git","svn_url":"https://github.com/rackerlabs/blueflood","homepage":"http://www.blueflood.io","size":11108,"stargazers_count":328,"watchers_count":328,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":43,"mirror_url":null,"open_issues_count":31,"forks":43,"open_issues":31,"watchers":328,"default_branch":"master"}},"base":{"label":"rackerlabs:master","ref":"master","sha":"10ca96311e71adc913ee30458ef70d83423399f5","user":{"login":"rackerlabs","id":84293,"avatar_url":"https://avatars.githubusercontent.com/u/84293?v=3","gravatar_id":"","url":"https://api.github.com/users/rackerlabs","html_url":"https://github.com/rackerlabs","followers_url":"https://api.github.com/users/rackerlabs/followers","following_url":"https://api.github.com/users/rackerlabs/following{/other_user}","gists_url":"https://api.github.com/users/rackerlabs/gists{/gist_id}","starred_url":"https://api.github.com/users/rackerlabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rackerlabs/subscriptions","organizations_url":"https://api.github.com/users/rackerlabs/orgs","repos_url":"https://api.github.com/users/rackerlabs/repos","events_url":"https://api.github.com/users/rackerlabs/events{/privacy}","received_events_url":"https://api.github.com/users/rackerlabs/received_events","type":"Organization","site_admin":false},"repo":{"id":10081109,"name":"blueflood","full_name":"rackerlabs/blueflood","owner":{"login":"rackerlabs","id":84293,"avatar_url":"https://avatars.githubusercontent.com/u/84293?v=3","gravatar_id":"","url":"https://api.github.com/users/rackerlabs","html_url":"https://github.com/rackerlabs","followers_url":"https://api.github.com/users/rackerlabs/followers","following_url":"https://api.github.com/users/rackerlabs/following{/other_user}","gists_url":"https://api.github.com/users/rackerlabs/gists{/gist_id}","starred_url":"https://api.github.com/users/rackerlabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rackerlabs/subscriptions","organizations_url":"https://api.github.com/users/rackerlabs/orgs","repos_url":"https://api.github.com/users/rackerlabs/repos","events_url":"https://api.github.com/users/rackerlabs/events{/privacy}","received_events_url":"https://api.github.com/users/rackerlabs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/rackerlabs/blueflood","description":"A distributed system designed to ingest and process time series data","fork":false,"url":"https://api.github.com/repos/rackerlabs/blueflood","forks_url":"https://api.github.com/repos/rackerlabs/blueflood/forks","keys_url":"https://api.github.com/repos/rackerlabs/blueflood/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rackerlabs/blueflood/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rackerlabs/blueflood/teams","hooks_url":"https://api.github.com/repos/rackerlabs/blueflood/hooks","issue_events_url":"https://api.github.com/repos/rackerlabs/blueflood/issues/events{/number}","events_url":"https://api.github.com/repos/rackerlabs/blueflood/events","assignees_url":"https://api.github.com/repos/rackerlabs/blueflood/assignees{/user}","branches_url":"https://api.github.com/repos/rackerlabs/blueflood/branches{/branch}","tags_url":"https://api.github.com/repos/rackerlabs/blueflood/tags","blobs_url":"https://api.github.com/repos/rackerlabs/blueflood/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rackerlabs/blueflood/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rackerlabs/blueflood/git/refs{/sha}","trees_url":"https://api.github.com/repos/rackerlabs/blueflood/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rackerlabs/blueflood/statuses/{sha}","languages_url":"https://api.github.com/repos/rackerlabs/blueflood/languages","stargazers_url":"https://api.github.com/repos/rackerlabs/blueflood/stargazers","contributors_url":"https://api.github.com/repos/rackerlabs/blueflood/contributors","subscribers_url":"https://api.github.com/repos/rackerlabs/blueflood/subscribers","subscription_url":"https://api.github.com/repos/rackerlabs/blueflood/subscription","commits_url":"https://api.github.com/repos/rackerlabs/blueflood/commits{/sha}","git_commits_url":"https://api.github.com/repos/rackerlabs/blueflood/git/commits{/sha}","comments_url":"https://api.github.com/repos/rackerlabs/blueflood/comments{/number}","issue_comment_url":"https://api.github.com/repos/rackerlabs/blueflood/issues/comments{/number}","contents_url":"https://api.github.com/repos/rackerlabs/blueflood/contents/{+path}","compare_url":"https://api.github.com/repos/rackerlabs/blueflood/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rackerlabs/blueflood/merges","archive_url":"https://api.github.com/repos/rackerlabs/blueflood/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rackerlabs/blueflood/downloads","issues_url":"https://api.github.com/repos/rackerlabs/blueflood/issues{/number}","pulls_url":"https://api.github.com/repos/rackerlabs/blueflood/pulls{/number}","milestones_url":"https://api.github.com/repos/rackerlabs/blueflood/milestones{/number}","notifications_url":"https://api.github.com/repos/rackerlabs/blueflood/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rackerlabs/blueflood/labels{/name}","releases_url":"https://api.github.com/repos/rackerlabs/blueflood/releases{/id}","created_at":"2013-05-15T14:50:39Z","updated_at":"2015-06-24T20:11:12Z","pushed_at":"2015-06-24T20:23:09Z","git_url":"git://github.com/rackerlabs/blueflood.git","ssh_url":"git@github.com:rackerlabs/blueflood.git","clone_url":"https://github.com/rackerlabs/blueflood.git","svn_url":"https://github.com/rackerlabs/blueflood","homepage":"http://www.blueflood.io","size":11108,"stargazers_count":328,"watchers_count":328,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":43,"mirror_url":null,"open_issues_count":31,"forks":43,"open_issues":31,"watchers":328,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/rackerlabs/blueflood/pulls/487"},"html":{"href":"https://github.com/rackerlabs/blueflood/pull/487"},"issue":{"href":"https://api.github.com/repos/rackerlabs/blueflood/issues/487"},"comments":{"href":"https://api.github.com/repos/rackerlabs/blueflood/issues/487/comments"},"review_comments":{"href":"https://api.github.com/repos/rackerlabs/blueflood/pulls/487/comments"},"review_comment":{"href":"https://api.github.com/repos/rackerlabs/blueflood/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/rackerlabs/blueflood/pulls/487/commits"},"statuses":{"href":"https://api.github.com/repos/rackerlabs/blueflood/statuses/2bb3567968b7f2ce4bfaadc2a753df2c2573a36a"}}}}