{"action":"created","issue":{"url":"https://api.github.com/repos/dirigodev/DirigoEdge/issues/148","labels_url":"https://api.github.com/repos/dirigodev/DirigoEdge/issues/148/labels{/name}","comments_url":"https://api.github.com/repos/dirigodev/DirigoEdge/issues/148/comments","events_url":"https://api.github.com/repos/dirigodev/DirigoEdge/issues/148/events","html_url":"https://github.com/dirigodev/DirigoEdge/pull/148","id":94968987,"number":148,"title":"Add Site Specific Timezone, closes #79","user":{"login":"Feasoron","id":1660215,"avatar_url":"https://avatars.githubusercontent.com/u/1660215?v=3","gravatar_id":"","url":"https://api.github.com/users/Feasoron","html_url":"https://github.com/Feasoron","followers_url":"https://api.github.com/users/Feasoron/followers","following_url":"https://api.github.com/users/Feasoron/following{/other_user}","gists_url":"https://api.github.com/users/Feasoron/gists{/gist_id}","starred_url":"https://api.github.com/users/Feasoron/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Feasoron/subscriptions","organizations_url":"https://api.github.com/users/Feasoron/orgs","repos_url":"https://api.github.com/users/Feasoron/repos","events_url":"https://api.github.com/users/Feasoron/events{/privacy}","received_events_url":"https://api.github.com/users/Feasoron/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":{"login":"justincolangelo","id":1440809,"avatar_url":"https://avatars.githubusercontent.com/u/1440809?v=3","gravatar_id":"","url":"https://api.github.com/users/justincolangelo","html_url":"https://github.com/justincolangelo","followers_url":"https://api.github.com/users/justincolangelo/followers","following_url":"https://api.github.com/users/justincolangelo/following{/other_user}","gists_url":"https://api.github.com/users/justincolangelo/gists{/gist_id}","starred_url":"https://api.github.com/users/justincolangelo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/justincolangelo/subscriptions","organizations_url":"https://api.github.com/users/justincolangelo/orgs","repos_url":"https://api.github.com/users/justincolangelo/repos","events_url":"https://api.github.com/users/justincolangelo/events{/privacy}","received_events_url":"https://api.github.com/users/justincolangelo/received_events","type":"User","site_admin":false},"milestone":null,"comments":6,"created_at":"2015-07-14T15:11:35Z","updated_at":"2015-07-15T19:33:22Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/dirigodev/DirigoEdge/pulls/148","html_url":"https://github.com/dirigodev/DirigoEdge/pull/148","diff_url":"https://github.com/dirigodev/DirigoEdge/pull/148.diff","patch_url":"https://github.com/dirigodev/DirigoEdge/pull/148.patch"},"body":"Adds support for a sitewide timezone. Once this is in place, all DateTimes that are sent to the server in any post should be converted to UTC from the site timezone, and all views will be given the local timezone rather than UTC. So long as new models are set up with datetimes (or nullable datetimes) as properties, this code should process them.\r\n\r\nTo make this work we have a bunch of changes\r\n* A new SiteConfiguration table that does key/value pairs\r\n* A new Settings initizializer that is called at app start. \r\n    * This combined with the new table means that we can add new config settings to Edge, add a sane default value in the init and any site can be upgrade quickly and cleanly without any risk of explosions\r\n* The site settings admin page has been edited to add the new timezone and take a controller-specific model rather than the SiteSetting entity\r\n*  Added a new SiteTime static class. This is used to access the site time zone safely, loading it on demand from the config table and falling back to UTC on any error. This code is written so as to always return a value on errors. \r\n\r\nI will happily walk anyone through the new DateTime processing code, but the basic way that it works is this:\r\n\r\n* The TimeZoneConverter Attribute has been added to the WebBaseController and the WebBaseAdminController. This uses OnActionExecuting to call into the TimeUtils (see below) with the proper conversion method for inbound/outbound\r\n* The TimeUtils uses reflection to iterate over all of the properties in the model object passed to it.\r\n    * If the property is a DateTime or DateTime?, it is converted\r\n    * If it is a list of DateTime or DateTime?, it is replaced with a new list with the values converted. Without specifically writing code for every list type (Ordered lists, Arrays, etc) I couldn't find a way to support all list types, so right now we only support actual Lists.\r\n    *If it is a Dirigo namespaced object, we recursively process that so that all of its members will be converted\r\n    * if it is any enumerable type of Dirigo namespaced objects, we recursively process all of them in order to convert of its memebers\r\n    * This code uses method delegates, so the exact same code is run for converting to and from local timezone, with only the conversion method being different."},"comment":{"url":"https://api.github.com/repos/dirigodev/DirigoEdge/issues/comments/121722162","html_url":"https://github.com/dirigodev/DirigoEdge/pull/148#issuecomment-121722162","issue_url":"https://api.github.com/repos/dirigodev/DirigoEdge/issues/148","id":121722162,"user":{"login":"Feasoron","id":1660215,"avatar_url":"https://avatars.githubusercontent.com/u/1660215?v=3","gravatar_id":"","url":"https://api.github.com/users/Feasoron","html_url":"https://github.com/Feasoron","followers_url":"https://api.github.com/users/Feasoron/followers","following_url":"https://api.github.com/users/Feasoron/following{/other_user}","gists_url":"https://api.github.com/users/Feasoron/gists{/gist_id}","starred_url":"https://api.github.com/users/Feasoron/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Feasoron/subscriptions","organizations_url":"https://api.github.com/users/Feasoron/orgs","repos_url":"https://api.github.com/users/Feasoron/repos","events_url":"https://api.github.com/users/Feasoron/events{/privacy}","received_events_url":"https://api.github.com/users/Feasoron/received_events","type":"User","site_admin":false},"created_at":"2015-07-15T19:33:22Z","updated_at":"2015-07-15T19:33:22Z","body":"The model had members that weren't properties. Updated, and it works. "}}