@openui5/sap.ui.core 1.98.0 → 1.99.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (351) hide show
  1. package/.eslintrc.json +32 -1
  2. package/package.json +1 -1
  3. package/src/jquery.sap.global.js +1 -1
  4. package/src/jquery.sap.mobile.js +29 -11
  5. package/src/jquery.sap.properties.js +1 -1
  6. package/src/jquery.sap.resources.js +1 -1
  7. package/src/jquery.sap.script.js +1 -1
  8. package/src/jquery.sap.storage.js +3 -3
  9. package/src/sap/base/util/restricted/_CancelablePromise.js +1 -1
  10. package/src/sap/base/util/restricted/_castArray.js +1 -1
  11. package/src/sap/base/util/restricted/_compact.js +1 -1
  12. package/src/sap/base/util/restricted/_curry.js +1 -1
  13. package/src/sap/base/util/restricted/_debounce.js +1 -1
  14. package/src/sap/base/util/restricted/_difference.js +1 -1
  15. package/src/sap/base/util/restricted/_differenceBy.js +1 -1
  16. package/src/sap/base/util/restricted/_differenceWith.js +1 -1
  17. package/src/sap/base/util/restricted/_flatMap.js +1 -1
  18. package/src/sap/base/util/restricted/_flatMapDeep.js +1 -1
  19. package/src/sap/base/util/restricted/_flatMapDepth.js +1 -1
  20. package/src/sap/base/util/restricted/_flatten.js +1 -1
  21. package/src/sap/base/util/restricted/_flattenDeep.js +1 -1
  22. package/src/sap/base/util/restricted/_flattenDepth.js +1 -1
  23. package/src/sap/base/util/restricted/_intersection.js +1 -1
  24. package/src/sap/base/util/restricted/_intersectionBy.js +1 -1
  25. package/src/sap/base/util/restricted/_intersectionWith.js +1 -1
  26. package/src/sap/base/util/restricted/_isEqual.js +1 -1
  27. package/src/sap/base/util/restricted/_isEqualWith.js +1 -1
  28. package/src/sap/base/util/restricted/_isNil.js +1 -1
  29. package/src/sap/base/util/restricted/_max.js +1 -1
  30. package/src/sap/base/util/restricted/_merge.js +1 -1
  31. package/src/sap/base/util/restricted/_mergeWith.js +1 -1
  32. package/src/sap/base/util/restricted/_min.js +1 -1
  33. package/src/sap/base/util/restricted/_omit.js +1 -1
  34. package/src/sap/base/util/restricted/_pick.js +1 -1
  35. package/src/sap/base/util/restricted/_pickBy.js +1 -1
  36. package/src/sap/base/util/restricted/_throttle.js +1 -1
  37. package/src/sap/base/util/restricted/_toArray.js +1 -1
  38. package/src/sap/base/util/restricted/_union.js +1 -1
  39. package/src/sap/base/util/restricted/_unionBy.js +1 -1
  40. package/src/sap/base/util/restricted/_unionWith.js +1 -1
  41. package/src/sap/base/util/restricted/_uniq.js +1 -1
  42. package/src/sap/base/util/restricted/_uniqBy.js +1 -1
  43. package/src/sap/base/util/restricted/_uniqWith.js +1 -1
  44. package/src/sap/base/util/restricted/_without.js +1 -1
  45. package/src/sap/base/util/restricted/_xor.js +1 -1
  46. package/src/sap/base/util/restricted/_xorBy.js +1 -1
  47. package/src/sap/base/util/restricted/_xorWith.js +1 -1
  48. package/src/sap/base/util/restricted/_zipObject.js +1 -1
  49. package/src/sap/base/util/restricted/_zipObjectDeep.js +1 -1
  50. package/src/sap/ui/Device.js +3 -3
  51. package/src/sap/ui/Global.js +4 -4
  52. package/src/sap/ui/VersionInfo.js +13 -10
  53. package/src/sap/ui/base/BindingParser.js +34 -7
  54. package/src/sap/ui/base/Event.js +1 -1
  55. package/src/sap/ui/base/EventProvider.js +1 -1
  56. package/src/sap/ui/base/Interface.js +1 -1
  57. package/src/sap/ui/base/ManagedObject.js +32 -22
  58. package/src/sap/ui/base/ManagedObjectMetadata.js +1 -1
  59. package/src/sap/ui/base/Metadata.js +1 -1
  60. package/src/sap/ui/base/Object.js +1 -1
  61. package/src/sap/ui/base/ObjectPool.js +1 -1
  62. package/src/sap/ui/core/.library +1 -1
  63. package/src/sap/ui/core/BusyIndicator.js +1 -1
  64. package/src/sap/ui/core/Component.js +3 -3
  65. package/src/sap/ui/core/ComponentContainer.js +1 -1
  66. package/src/sap/ui/core/ComponentMetadata.js +1 -1
  67. package/src/sap/ui/core/ComponentSupport.js +1 -1
  68. package/src/sap/ui/core/Configuration.js +77 -10
  69. package/src/sap/ui/core/Control.js +2 -1
  70. package/src/sap/ui/core/Core.js +3 -3
  71. package/src/sap/ui/core/CustomData.js +1 -1
  72. package/src/sap/ui/core/DeclarativeSupport.js +1 -1
  73. package/src/sap/ui/core/Element.js +4 -7
  74. package/src/sap/ui/core/ElementMetadata.js +1 -1
  75. package/src/sap/ui/core/EnabledPropagator.js +1 -1
  76. package/src/sap/ui/core/EventBus.js +1 -1
  77. package/src/sap/ui/core/ExtensionPoint.js +1 -1
  78. package/src/sap/ui/core/FocusHandler.js +1 -1
  79. package/src/sap/ui/core/Fragment.js +1 -1
  80. package/src/sap/ui/core/HTML.js +1 -1
  81. package/src/sap/ui/core/HTMLRenderer.js +1 -1
  82. package/src/sap/ui/core/History.js +1 -1
  83. package/src/sap/ui/core/Icon.js +1 -1
  84. package/src/sap/ui/core/IconRenderer.js +1 -1
  85. package/src/sap/ui/core/IndicationColorSupport.js +1 -1
  86. package/src/sap/ui/core/IntervalTrigger.js +1 -1
  87. package/src/sap/ui/core/InvisibleMessage.js +1 -1
  88. package/src/sap/ui/core/InvisibleRenderer.js +1 -1
  89. package/src/sap/ui/core/InvisibleText.js +1 -1
  90. package/src/sap/ui/core/Item.js +1 -1
  91. package/src/sap/ui/core/LabelEnablement.js +9 -2
  92. package/src/sap/ui/core/LayoutData.js +1 -1
  93. package/src/sap/ui/core/ListItem.js +1 -1
  94. package/src/sap/ui/core/LocalBusyIndicator.js +1 -1
  95. package/src/sap/ui/core/LocalBusyIndicatorRenderer.js +2 -2
  96. package/src/sap/ui/core/Locale.js +1 -1
  97. package/src/sap/ui/core/LocaleData.js +37 -2
  98. package/src/sap/ui/core/Manifest.js +1 -1
  99. package/src/sap/ui/core/Message.js +1 -1
  100. package/src/sap/ui/core/Popup.js +2 -2
  101. package/src/sap/ui/core/RenderManager.js +1 -1
  102. package/src/sap/ui/core/Renderer.js +1 -1
  103. package/src/sap/ui/core/ResizeHandler.js +1 -1
  104. package/src/sap/ui/core/ScrollBar.js +1 -1
  105. package/src/sap/ui/core/ScrollBarRenderer.js +1 -1
  106. package/src/sap/ui/core/SeparatorItem.js +1 -1
  107. package/src/sap/ui/core/Title.js +1 -1
  108. package/src/sap/ui/core/TooltipBase.js +1 -1
  109. package/src/sap/ui/core/UIArea.js +1 -1
  110. package/src/sap/ui/core/UIComponent.js +1 -1
  111. package/src/sap/ui/core/UIComponentMetadata.js +1 -1
  112. package/src/sap/ui/core/ValueStateSupport.js +1 -1
  113. package/src/sap/ui/core/VariantLayoutData.js +1 -1
  114. package/src/sap/ui/core/XMLComposite.js +1 -1
  115. package/src/sap/ui/core/XMLCompositeMetadata.js +1 -1
  116. package/src/sap/ui/core/_IconRegistry.js +10 -1
  117. package/src/sap/ui/core/date/Japanese.js +1 -1
  118. package/src/sap/ui/core/delegate/ItemNavigation.js +1 -1
  119. package/src/sap/ui/core/delegate/ScrollEnablement.js +9 -6
  120. package/src/sap/ui/core/dnd/DragDropBase.js +1 -1
  121. package/src/sap/ui/core/dnd/DragDropInfo.js +1 -1
  122. package/src/sap/ui/core/dnd/DragInfo.js +1 -1
  123. package/src/sap/ui/core/dnd/DropInfo.js +1 -1
  124. package/src/sap/ui/core/format/DateFormat.js +524 -172
  125. package/src/sap/ui/core/format/DateFormatTimezoneDisplay.js +43 -0
  126. package/src/sap/ui/core/format/ListFormat.js +2 -2
  127. package/src/sap/ui/core/format/NumberFormat.js +190 -56
  128. package/src/sap/ui/core/format/TimezoneUtil.js +248 -0
  129. package/src/sap/ui/core/hyphenation/Hyphenation.js +1 -1
  130. package/src/sap/ui/core/library.js +5 -5
  131. package/src/sap/ui/core/message/ControlMessageProcessor.js +1 -1
  132. package/src/sap/ui/core/message/Message.js +1 -1
  133. package/src/sap/ui/core/message/MessageManager.js +1 -1
  134. package/src/sap/ui/core/message/MessageParser.js +1 -1
  135. package/src/sap/ui/core/message/MessageProcessor.js +1 -1
  136. package/src/sap/ui/core/messagebundle.properties +4 -0
  137. package/src/sap/ui/core/messagebundle_ar.properties +2 -0
  138. package/src/sap/ui/core/messagebundle_bg.properties +7 -5
  139. package/src/sap/ui/core/messagebundle_ca.properties +2 -0
  140. package/src/sap/ui/core/messagebundle_cs.properties +2 -0
  141. package/src/sap/ui/core/messagebundle_cy.properties +2 -0
  142. package/src/sap/ui/core/messagebundle_da.properties +2 -0
  143. package/src/sap/ui/core/messagebundle_de.properties +3 -1
  144. package/src/sap/ui/core/messagebundle_el.properties +2 -0
  145. package/src/sap/ui/core/messagebundle_en.properties +2 -0
  146. package/src/sap/ui/core/messagebundle_en_GB.properties +2 -0
  147. package/src/sap/ui/core/messagebundle_en_US_sappsd.properties +2 -0
  148. package/src/sap/ui/core/messagebundle_en_US_saprigi.properties +1 -0
  149. package/src/sap/ui/core/messagebundle_en_US_saptrc.properties +2 -0
  150. package/src/sap/ui/core/messagebundle_es.properties +2 -0
  151. package/src/sap/ui/core/messagebundle_es_MX.properties +2 -0
  152. package/src/sap/ui/core/messagebundle_et.properties +2 -0
  153. package/src/sap/ui/core/messagebundle_fi.properties +2 -0
  154. package/src/sap/ui/core/messagebundle_fr.properties +2 -0
  155. package/src/sap/ui/core/messagebundle_fr_CA.properties +2 -0
  156. package/src/sap/ui/core/messagebundle_hi.properties +2 -0
  157. package/src/sap/ui/core/messagebundle_hr.properties +2 -0
  158. package/src/sap/ui/core/messagebundle_hu.properties +2 -0
  159. package/src/sap/ui/core/messagebundle_id.properties +4 -2
  160. package/src/sap/ui/core/messagebundle_it.properties +2 -0
  161. package/src/sap/ui/core/messagebundle_iw.properties +2 -0
  162. package/src/sap/ui/core/messagebundle_ja.properties +2 -0
  163. package/src/sap/ui/core/messagebundle_kk.properties +2 -0
  164. package/src/sap/ui/core/messagebundle_ko.properties +2 -0
  165. package/src/sap/ui/core/messagebundle_lt.properties +2 -0
  166. package/src/sap/ui/core/messagebundle_lv.properties +3 -1
  167. package/src/sap/ui/core/messagebundle_ms.properties +2 -0
  168. package/src/sap/ui/core/messagebundle_nl.properties +2 -0
  169. package/src/sap/ui/core/messagebundle_no.properties +2 -0
  170. package/src/sap/ui/core/messagebundle_pl.properties +2 -0
  171. package/src/sap/ui/core/messagebundle_pt.properties +2 -0
  172. package/src/sap/ui/core/messagebundle_pt_PT.properties +2 -0
  173. package/src/sap/ui/core/messagebundle_ro.properties +2 -0
  174. package/src/sap/ui/core/messagebundle_ru.properties +2 -0
  175. package/src/sap/ui/core/messagebundle_sh.properties +2 -0
  176. package/src/sap/ui/core/messagebundle_sk.properties +2 -0
  177. package/src/sap/ui/core/messagebundle_sl.properties +2 -0
  178. package/src/sap/ui/core/messagebundle_sv.properties +2 -0
  179. package/src/sap/ui/core/messagebundle_th.properties +2 -0
  180. package/src/sap/ui/core/messagebundle_tr.properties +2 -0
  181. package/src/sap/ui/core/messagebundle_uk.properties +2 -0
  182. package/src/sap/ui/core/messagebundle_vi.properties +2 -0
  183. package/src/sap/ui/core/messagebundle_zh_CN.properties +2 -0
  184. package/src/sap/ui/core/messagebundle_zh_TW.properties +2 -0
  185. package/src/sap/ui/core/mvc/HTMLView.js +1 -1
  186. package/src/sap/ui/core/mvc/HTMLViewRenderer.js +1 -1
  187. package/src/sap/ui/core/mvc/JSONView.js +1 -1
  188. package/src/sap/ui/core/mvc/JSONViewRenderer.js +1 -1
  189. package/src/sap/ui/core/mvc/JSView.js +1 -1
  190. package/src/sap/ui/core/mvc/JSViewRenderer.js +1 -1
  191. package/src/sap/ui/core/mvc/TemplateView.js +1 -1
  192. package/src/sap/ui/core/mvc/TemplateViewRenderer.js +1 -1
  193. package/src/sap/ui/core/mvc/View.js +1 -1
  194. package/src/sap/ui/core/mvc/ViewRenderer.js +1 -1
  195. package/src/sap/ui/core/mvc/XMLView.js +1 -1
  196. package/src/sap/ui/core/plugin/DeclarativeSupport.js +1 -1
  197. package/src/sap/ui/core/plugin/LessSupport.js +1 -1
  198. package/src/sap/ui/core/plugin/TemplatingSupport.js +1 -1
  199. package/src/sap/ui/core/postmessage/Bus.js +1 -1
  200. package/src/sap/ui/core/postmessage/confirmationDialog.js +1 -1
  201. package/src/sap/ui/core/routing/Router.js +1 -1
  202. package/src/sap/ui/core/search/OpenSearchProvider.js +1 -1
  203. package/src/sap/ui/core/search/SearchProvider.js +1 -1
  204. package/src/sap/ui/core/service/Service.js +1 -1
  205. package/src/sap/ui/core/service/ServiceFactory.js +1 -1
  206. package/src/sap/ui/core/service/ServiceFactoryRegistry.js +1 -1
  207. package/src/sap/ui/core/support/Plugin.js +1 -1
  208. package/src/sap/ui/core/support/Support.js +1 -1
  209. package/src/sap/ui/core/support/plugins/ControlTree.js +1 -1
  210. package/src/sap/ui/core/support/plugins/Interaction.js +1 -1
  211. package/src/sap/ui/core/support/plugins/LocalStorage.js +1 -1
  212. package/src/sap/ui/core/support/plugins/Performance.js +1 -1
  213. package/src/sap/ui/core/support/plugins/Selector.js +1 -1
  214. package/src/sap/ui/core/support/plugins/TechInfo.js +1 -1
  215. package/src/sap/ui/core/support/plugins/Trace.js +1 -1
  216. package/src/sap/ui/core/support/plugins/ViewInfo.js +1 -1
  217. package/src/sap/ui/core/themes/base/fonts/SAP-icons.woff2 +0 -0
  218. package/src/sap/ui/core/tmpl/DOMAttribute.js +1 -1
  219. package/src/sap/ui/core/tmpl/DOMElement.js +1 -1
  220. package/src/sap/ui/core/tmpl/HandlebarsTemplate.js +1 -1
  221. package/src/sap/ui/core/tmpl/Template.js +1 -1
  222. package/src/sap/ui/core/tmpl/TemplateControl.js +1 -1
  223. package/src/sap/ui/core/util/AsyncHintsHelper.js +1 -1
  224. package/src/sap/ui/core/util/Export.js +1 -1
  225. package/src/sap/ui/core/util/ExportCell.js +1 -1
  226. package/src/sap/ui/core/util/ExportColumn.js +1 -1
  227. package/src/sap/ui/core/util/ExportRow.js +1 -1
  228. package/src/sap/ui/core/util/ExportType.js +1 -1
  229. package/src/sap/ui/core/util/ExportTypeCSV.js +1 -1
  230. package/src/sap/ui/core/util/File.js +1 -1
  231. package/src/sap/ui/core/util/LibraryInfo.js +1 -1
  232. package/src/sap/ui/core/util/MockServer.js +19 -17
  233. package/src/sap/ui/core/util/PasteHelper.js +4 -4
  234. package/src/sap/ui/core/util/XMLPreprocessor.js +16 -4
  235. package/src/sap/ui/core/util/reflection/XmlTreeModifier.js +1 -1
  236. package/src/sap/ui/core/util/serializer/HTMLViewSerializer.js +1 -1
  237. package/src/sap/ui/core/util/serializer/Serializer.js +1 -1
  238. package/src/sap/ui/core/util/serializer/ViewSerializer.js +1 -1
  239. package/src/sap/ui/core/util/serializer/XMLViewSerializer.js +1 -1
  240. package/src/sap/ui/core/util/serializer/delegate/Delegate.js +1 -1
  241. package/src/sap/ui/core/util/serializer/delegate/HTML.js +1 -1
  242. package/src/sap/ui/core/util/serializer/delegate/XML.js +1 -1
  243. package/src/sap/ui/core/ws/ReadyState.js +1 -1
  244. package/src/sap/ui/core/ws/SapPcpWebSocket.js +1 -1
  245. package/src/sap/ui/core/ws/WebSocket.js +1 -1
  246. package/src/sap/ui/debug/ControlTree.js +1 -1
  247. package/src/sap/ui/debug/DebugEnv.js +1 -1
  248. package/src/sap/ui/debug/PropertyList.js +1 -1
  249. package/src/sap/ui/dom/includeStylesheet.js +8 -3
  250. package/src/sap/ui/events/jquery/EventExtension.js +1 -1
  251. package/src/sap/ui/model/Binding.js +4 -3
  252. package/src/sap/ui/model/ClientModel.js +1 -1
  253. package/src/sap/ui/model/ClientTreeBinding.js +1 -1
  254. package/src/sap/ui/model/CompositeBinding.js +1 -1
  255. package/src/sap/ui/model/CompositeDataState.js +1 -1
  256. package/src/sap/ui/model/CompositeType.js +1 -1
  257. package/src/sap/ui/model/ContextBinding.js +1 -1
  258. package/src/sap/ui/model/DataState.js +1 -1
  259. package/src/sap/ui/model/MetaModel.js +1 -2
  260. package/src/sap/ui/model/Model.js +1 -1
  261. package/src/sap/ui/model/SelectionModel.js +1 -1
  262. package/src/sap/ui/model/SimpleType.js +1 -1
  263. package/src/sap/ui/model/TreeAutoExpandMode.js +1 -1
  264. package/src/sap/ui/model/Type.js +1 -1
  265. package/src/sap/ui/model/analytics/AnalyticalBinding.js +1 -2
  266. package/src/sap/ui/model/base/ManagedObjectModel.js +1 -1
  267. package/src/sap/ui/model/json/JSONListBinding.js +1 -1
  268. package/src/sap/ui/model/json/JSONModel.js +1 -1
  269. package/src/sap/ui/model/json/JSONPropertyBinding.js +1 -1
  270. package/src/sap/ui/model/message/MessageListBinding.js +1 -1
  271. package/src/sap/ui/model/message/MessageModel.js +1 -1
  272. package/src/sap/ui/model/message/MessagePropertyBinding.js +1 -1
  273. package/src/sap/ui/model/odata/ODataAnnotations.js +1 -1
  274. package/src/sap/ui/model/odata/ODataListBinding.js +1 -1
  275. package/src/sap/ui/model/odata/ODataMessageParser.js +1 -1
  276. package/src/sap/ui/model/odata/ODataMetaModel.js +1 -1
  277. package/src/sap/ui/model/odata/ODataMetadata.js +3 -3
  278. package/src/sap/ui/model/odata/ODataModel.js +2 -2
  279. package/src/sap/ui/model/odata/ODataTreeBinding.js +1 -1
  280. package/src/sap/ui/model/odata/type/Boolean.js +1 -1
  281. package/src/sap/ui/model/odata/type/Byte.js +1 -1
  282. package/src/sap/ui/model/odata/type/Currency.js +1 -1
  283. package/src/sap/ui/model/odata/type/Date.js +1 -1
  284. package/src/sap/ui/model/odata/type/DateTime.js +1 -1
  285. package/src/sap/ui/model/odata/type/DateTimeBase.js +1 -1
  286. package/src/sap/ui/model/odata/type/DateTimeOffset.js +1 -1
  287. package/src/sap/ui/model/odata/type/DateTimeWithTimezone.js +338 -0
  288. package/src/sap/ui/model/odata/type/Decimal.js +1 -1
  289. package/src/sap/ui/model/odata/type/Double.js +1 -1
  290. package/src/sap/ui/model/odata/type/Guid.js +1 -1
  291. package/src/sap/ui/model/odata/type/Int.js +1 -1
  292. package/src/sap/ui/model/odata/type/Int16.js +1 -1
  293. package/src/sap/ui/model/odata/type/Int32.js +1 -1
  294. package/src/sap/ui/model/odata/type/Int64.js +1 -1
  295. package/src/sap/ui/model/odata/type/ODataType.js +1 -1
  296. package/src/sap/ui/model/odata/type/Raw.js +1 -1
  297. package/src/sap/ui/model/odata/type/SByte.js +1 -1
  298. package/src/sap/ui/model/odata/type/Single.js +1 -1
  299. package/src/sap/ui/model/odata/type/Stream.js +1 -1
  300. package/src/sap/ui/model/odata/type/String.js +1 -1
  301. package/src/sap/ui/model/odata/type/Time.js +1 -1
  302. package/src/sap/ui/model/odata/type/TimeOfDay.js +1 -1
  303. package/src/sap/ui/model/odata/type/Unit.js +1 -1
  304. package/src/sap/ui/model/odata/v2/Context.js +1 -1
  305. package/src/sap/ui/model/odata/v2/ODataAnnotations.js +1 -1
  306. package/src/sap/ui/model/odata/v2/ODataContextBinding.js +8 -4
  307. package/src/sap/ui/model/odata/v2/ODataListBinding.js +32 -26
  308. package/src/sap/ui/model/odata/v2/ODataModel.js +11 -6
  309. package/src/sap/ui/model/odata/v2/ODataTreeBinding.js +3 -4
  310. package/src/sap/ui/model/odata/v4/AnnotationHelper.js +16 -17
  311. package/src/sap/ui/model/odata/v4/Context.js +90 -52
  312. package/src/sap/ui/model/odata/v4/ODataBinding.js +16 -9
  313. package/src/sap/ui/model/odata/v4/ODataContextBinding.js +129 -170
  314. package/src/sap/ui/model/odata/v4/ODataListBinding.js +205 -179
  315. package/src/sap/ui/model/odata/v4/ODataMetaModel.js +91 -63
  316. package/src/sap/ui/model/odata/v4/ODataModel.js +316 -249
  317. package/src/sap/ui/model/odata/v4/ODataParentBinding.js +48 -25
  318. package/src/sap/ui/model/odata/v4/ODataPropertyBinding.js +63 -60
  319. package/src/sap/ui/model/odata/v4/_AnnotationHelperExpression.js +2 -1
  320. package/src/sap/ui/model/odata/v4/lib/_Cache.js +41 -10
  321. package/src/sap/ui/model/odata/v4/lib/_Helper.js +6 -2
  322. package/src/sap/ui/model/odata/v4/lib/_MetadataConverter.js +2 -2
  323. package/src/sap/ui/model/odata/v4/lib/_Requestor.js +20 -18
  324. package/src/sap/ui/model/odata/v4/lib/_V2Requestor.js +1 -1
  325. package/src/sap/ui/model/resource/ResourceModel.js +1 -1
  326. package/src/sap/ui/model/resource/ResourcePropertyBinding.js +1 -1
  327. package/src/sap/ui/model/type/Boolean.js +1 -1
  328. package/src/sap/ui/model/type/Currency.js +1 -1
  329. package/src/sap/ui/model/type/Date.js +1 -1
  330. package/src/sap/ui/model/type/DateInterval.js +1 -1
  331. package/src/sap/ui/model/type/DateTime.js +1 -1
  332. package/src/sap/ui/model/type/DateTimeInterval.js +1 -1
  333. package/src/sap/ui/model/type/FileSize.js +1 -1
  334. package/src/sap/ui/model/type/Float.js +1 -1
  335. package/src/sap/ui/model/type/Integer.js +1 -1
  336. package/src/sap/ui/model/type/String.js +1 -1
  337. package/src/sap/ui/model/type/Time.js +1 -1
  338. package/src/sap/ui/model/type/TimeInterval.js +1 -1
  339. package/src/sap/ui/model/type/Unit.js +1 -1
  340. package/src/sap/ui/model/xml/XMLListBinding.js +1 -1
  341. package/src/sap/ui/model/xml/XMLModel.js +1 -1
  342. package/src/sap/ui/model/xml/XMLPropertyBinding.js +1 -1
  343. package/src/sap/ui/performance/trace/Passport.js +3 -3
  344. package/src/sap/ui/qunit/utils/ControlIterator.js +1 -1
  345. package/src/sap/ui/qunit/utils/MemoryLeakCheck.js +1 -1
  346. package/src/sap/ui/test/Opa5.js +1 -1
  347. package/src/sap/ui/thirdparty/jqueryui/jquery-ui-datepicker.js +143 -3
  348. package/src/sap/ui/thirdparty/jqueryui/jquery-ui-position.js +8 -1
  349. package/src/sap/ui/thirdparty/mobify-carousel.js +1 -1
  350. package/src/sap/ui/util/Storage.js +1 -1
  351. package/src/ui5loader.js +1 -1
@@ -10,6 +10,8 @@ sap.ui.define([
10
10
  'sap/ui/core/Locale',
11
11
  'sap/ui/core/LocaleData',
12
12
  'sap/ui/core/date/UniversalDate',
13
+ 'sap/ui/core/format/TimezoneUtil',
14
+ 'sap/ui/core/format/DateFormatTimezoneDisplay',
13
15
  "sap/base/util/deepEqual",
14
16
  "sap/base/strings/formatMessage",
15
17
  "sap/base/Log",
@@ -20,6 +22,8 @@ sap.ui.define([
20
22
  Locale,
21
23
  LocaleData,
22
24
  UniversalDate,
25
+ TimezoneUtil,
26
+ DateFormatTimezoneDisplay,
23
27
  deepEqual,
24
28
  formatMessage,
25
29
  Log,
@@ -28,12 +32,20 @@ sap.ui.define([
28
32
  "use strict";
29
33
 
30
34
  /**
31
- * Constructor for DateFormat - must not be used: To get a DateFormat instance, please use getDateInstance, getDateTimeInstance or getTimeInstance.
35
+ * Constructor for DateFormat - must not be used:
36
+ * <ul>
37
+ * <li>To get a {@link sap.ui.core.format.DateFormat} instance, please use {@link sap.ui.core.format.DateFormat.getDateInstance}, {@link sap.ui.core.format.DateFormat.getDateTimeInstance} or {@link sap.ui.core.format.DateFormat.getTimeInstance}</li>
38
+ * <li>To get a {@link sap.ui.core.format.DateFormat.DateTimeWithTimezone} instance, please use {@link sap.ui.core.format.DateFormat.getDateTimeWithTimezoneInstance}</li>
39
+ * </ul>
32
40
  *
33
41
  * @class
34
42
  * The DateFormat is a static class for formatting and parsing single date and time values or date and time intervals according
35
43
  * to a set of format options.
36
44
  *
45
+ * Important:
46
+ * Every Date is converted with the timezone taken from {@link sap.ui.core.Configuration#getTimezone}.
47
+ * The timezone falls back to the browser's local timezone.
48
+ *
37
49
  * Supported format options are pattern based on Unicode LDML Date Format notation. Please note that only a subset of the LDML date symbols
38
50
  * is supported.
39
51
  * If no pattern is specified a default pattern according to the locale settings is used.
@@ -48,10 +60,21 @@ sap.ui.define([
48
60
  throw new Error();
49
61
  };
50
62
 
63
+ /**
64
+ * Internal enumeration to differentiate DateFormat types
65
+ */
66
+ var mDateFormatTypes = {
67
+ DATE: "date",
68
+ TIME: "time",
69
+ DATETIME: "datetime",
70
+ DATETIME_WITH_TIMEZONE: "datetimeWithTimezone"
71
+ };
72
+
51
73
  // Cache for parsed CLDR DatePattern
52
74
  var mCldrDatePattern = {};
53
75
 
54
76
  DateFormat.oDateInfo = {
77
+ type: mDateFormatTypes.DATE,
55
78
  oDefaultFormatOptions: {
56
79
  style: "medium",
57
80
  relativeScale: "day",
@@ -77,6 +100,7 @@ sap.ui.define([
77
100
  };
78
101
 
79
102
  DateFormat.oDateTimeInfo = {
103
+ type: mDateFormatTypes.DATETIME,
80
104
  oDefaultFormatOptions: {
81
105
  style: "medium",
82
106
  relativeScale: "auto",
@@ -106,7 +130,39 @@ sap.ui.define([
106
130
  aIntervalCompareFields: ["Era", "FullYear", "Quarter", "Month", "Week", "Date", "DayPeriod", "Hours", "Minutes", "Seconds"]
107
131
  };
108
132
 
133
+ DateFormat.oDateTimeWithTimezoneInfo = Object.assign({}, DateFormat.oDateTimeInfo, {
134
+ type: mDateFormatTypes.DATETIME_WITH_TIMEZONE,
135
+ // This function is used to transform the pattern of the fallbackFormatOptions to a timezone pattern
136
+ // based on the showTimezone format option.
137
+ getTimezonePattern: function(sPattern, sShowTimezone) {
138
+ if (sShowTimezone === DateFormatTimezoneDisplay.Only) {
139
+ return "VV";
140
+ } else if (sShowTimezone === DateFormatTimezoneDisplay.Hide) {
141
+ return sPattern;
142
+ } else {
143
+ return sPattern + " VV";
144
+ }
145
+ },
146
+ getPattern: function(oLocaleData, sStyle, sCalendarType, sShowTimezone) {
147
+ if (sShowTimezone === DateFormatTimezoneDisplay.Only) {
148
+ return "VV";
149
+ }
150
+ if (sShowTimezone === DateFormatTimezoneDisplay.Hide) {
151
+ return DateFormat.oDateTimeInfo.getPattern(oLocaleData, sStyle, sCalendarType);
152
+ }
153
+
154
+ // If style is mixed ("medium/short") split it and pass both parts separately
155
+ var iSlashIndex = sStyle.indexOf("/");
156
+ if (iSlashIndex > 0) {
157
+ return oLocaleData.getCombinedDateTimeWithTimezonePattern(sStyle.substr(0, iSlashIndex), sStyle.substr(iSlashIndex + 1), sCalendarType);
158
+ } else {
159
+ return oLocaleData.getCombinedDateTimeWithTimezonePattern(sStyle, sStyle, sCalendarType);
160
+ }
161
+ }
162
+ });
163
+
109
164
  DateFormat.oTimeInfo = {
165
+ type: mDateFormatTypes.TIME,
110
166
  oDefaultFormatOptions: {
111
167
  style: "medium",
112
168
  relativeScale: "auto",
@@ -176,7 +232,7 @@ sap.ui.define([
176
232
  * @param {string} [oFormatOptions.pattern] a datetime pattern in LDML format. It is not verified whether the pattern represents a full datetime.
177
233
  * @param {string} [oFormatOptions.style] can be either 'short, 'medium', 'long' or 'full'. For datetime you can also define mixed styles, separated with a slash, where the first part is the date style and the second part is the time style (e.g. "medium/short"). If no pattern is given, a locale dependent default datetime pattern of that style is used from the LocaleData class.
178
234
  * @param {boolean} [oFormatOptions.strictParsing] if true, by parsing it is checked if the value is a valid datetime
179
- * @param {boolean} [oFormatOptions.relative] if true, the date is formatted relatively to todays date if it is within the given day range, e.g. "today", "yesterday", "in 5 days"@param {boolean} [oFormatOptions.UTC] if true, the date is formatted and parsed as UTC instead of the local timezone
235
+ * @param {boolean} [oFormatOptions.relative] if true, the date is formatted relatively to today's date if it is within the given day range, e.g. "today", "yesterday", "in 5 days"
180
236
  * @param {int[]} [oFormatOptions.relativeRange] the day range used for relative formatting. If <code>oFormatOptions.relativeScale</code> is set to default value 'day', the relativeRange is by default [-6, 6], which means only the last 6 days, today and the next 6 days are formatted relatively. Otherwise when <code>oFormatOptions.relativeScale</code> is set to 'auto', all dates are formatted relatively.
181
237
  * @param {string} [oFormatOptions.relativeScale="day"] if 'auto' is set, new relative time format is switched on for all Date/Time Instances. The relative scale is chosen depending on the difference between the given date and now.
182
238
  * @param {string} [oFormatOptions.relativeStyle="wide"] @since 1.32.10, 1.34.4 the style of the relative format. The valid values are "wide", "short", "narrow"
@@ -194,6 +250,151 @@ sap.ui.define([
194
250
  return this.createInstance(oFormatOptions, oLocale, this.oDateTimeInfo);
195
251
  };
196
252
 
253
+ /**
254
+ * Interface for a timezone-specific DateFormat, which is able to format and parse a date
255
+ * based on a given timezone. The timezone is used to convert the given date, and also for
256
+ * timezone-related pattern symbols. The timezone is an IANA timezone ID, e.g. "America/New_York".
257
+ *
258
+ * @see sap.ui.core.format.DateFormat
259
+ *
260
+ * @author SAP SE
261
+ * @since 1.99
262
+ * @interface
263
+ * @name sap.ui.core.format.DateFormat.DateTimeWithTimezone
264
+ * @public
265
+ */
266
+
267
+ /**
268
+ * Format a date object to a string according to the given timezone and format options.
269
+ *
270
+ * @example <caption>Format option showTimezone: Show (default)</caption>
271
+ * var oDate = new Date(Date.UTC(2021, 11, 24, 13, 37));
272
+ *
273
+ * DateFormat.getDateTimeWithTimezoneInstance().format(oDate, "Europe/Berlin");
274
+ * // output: "Dec 24, 2021, 2:37:00 PM Europe/Berlin"
275
+ *
276
+ * DateFormat.getDateTimeWithTimezoneInstance().format(oDate, "America/New_York");
277
+ * // output: "Dec 24, 2021, 8:37:00 AM America/New_York"
278
+ *
279
+ * @example <caption>Format option showTimezone: Hide</caption>
280
+ * var oDate = new Date(Date.UTC(2021, 11, 24, 13, 37));
281
+ * DateFormat.getDateTimeWithTimezoneInstance({showTimezone: "Hide"}).format(oDate, "America/New_York");
282
+ * // output: "Dec 24, 2021, 8:37:00 AM"
283
+ *
284
+ * @example <caption>Format option showTimezone: Only</caption>
285
+ * var oDate = new Date(Date.UTC(2021, 11, 24, 13, 37));
286
+ * DateFormat.getDateTimeWithTimezoneInstance({showTimezone: "Only"}).format(oDate, "America/New_York");
287
+ * // output: "America/New_York"
288
+ *
289
+ * @param {Date} oJSDate The date to format
290
+ * @param {string} [sTimezone] The IANA timezone ID in which the date will be calculated and
291
+ * formatted e.g. "America/New_York". If omitted, the timezone will be taken from {@link sap.ui.core.Configuration#getTimezone}.
292
+ * @return {string} the formatted output value. If an invalid date is given, an empty string is returned.
293
+ * @name sap.ui.core.format.DateFormat.DateTimeWithTimezone.format
294
+ * @function
295
+ * @public
296
+ * @since 1.99
297
+ * @experimental As of 1.99.0 certain aspects of this API are not settled yet, i.e. the defaulting for the timezone parameter might change.
298
+ * To be on the safe side, always call with a valid timezone.
299
+ */
300
+
301
+ /**
302
+ * Parse a string which is formatted according to the given format options to an array
303
+ * containing a date object and the timezone.
304
+ *
305
+ * @example <caption>Format option showTimezone: Show (default)</caption>
306
+ * var oDate = new Date(Date.UTC(2021, 11, 24, 13, 37));
307
+ *
308
+ * DateFormat.getDateTimeWithTimezoneInstance().parse("Dec 24, 2021, 2:37:00 PM Europe/Berlin", "Europe/Berlin");
309
+ * // output: [oDate, "Europe/Berlin"]
310
+ *
311
+ * DateFormat.getDateTimeWithTimezoneInstance().parse("Dec 24, 2021, 8:37:00 AM America/New_York", "America/New_York");
312
+ * // output: [oDate, "America/New_York"]
313
+ *
314
+ * @example <caption>Format option showTimezone: Hide</caption>
315
+ * var oDate = new Date(Date.UTC(2021, 11, 24, 13, 37));
316
+ * DateFormat.getDateTimeWithTimezoneInstance({showTimezone: "Hide"}).parse("Dec 24, 2021, 8:37:00 AM", "America/New_York");
317
+ * // output: [oDate, undefined]
318
+ *
319
+ * @example <caption>Format option showTimezone: Only</caption>
320
+ * DateFormat.getDateTimeWithTimezoneInstance({showTimezone: "Only"}).parse("America/New_York", "America/New_York");
321
+ * // output: [undefined, "America/New_York"]
322
+ *
323
+ * @param {string} sValue the string containing a formatted date/time value
324
+ * @param {string} [sTimezone] The IANA timezone ID which should be used to convert the date
325
+ * e.g. "America/New_York". If omitted, the timezone will be taken from {@link sap.ui.core.Configuration#getTimezone}.
326
+ * @param {boolean} [bStrict] Whether to be strict with regards to the value ranges of date fields,
327
+ * e.g. for a month pattern of <code>MM</code> and a value range of [1-12]
328
+ * <code>strict</code> ensures that the value is within the range;
329
+ * if it is larger than <code>12</code> it cannot be parsed and <code>null</code> is returned
330
+ * @return {Array} the parsed values
331
+ * <ul>
332
+ * <li>An array containing datetime and timezone depending on the showTimezone option
333
+ * <ul>
334
+ * <li>"Show": [Date, string], e.g. [new Date("2021-11-13T13:22:33Z"), "America/New_York"]</li>
335
+ * <li>"Hide": [Date, undefined], e.g. [new Date("2021-11-13T13:22:33Z"), undefined]</li>
336
+ * <li>"Only": [undefined, string], e.g. [undefined, "America/New_York"]</li>
337
+ * </ul>
338
+ * </li>
339
+ * </ul>
340
+ *
341
+ * @public
342
+ * @name sap.ui.core.format.DateFormat.DateTimeWithTimezone.parse
343
+ * @function
344
+ * @since 1.99
345
+ * @experimental As of 1.99.0 certain aspects of this API are not settled yet, i.e. the defaulting for the timezone parameter might change.
346
+ * To be on the safe side, always call with a valid timezone.
347
+ */
348
+
349
+ /**
350
+ * Get a datetimeWithTimezone instance of the DateFormat, which can be used for formatting.
351
+ *
352
+ * @example
353
+ * // Timezone difference -5 hours, UTC Zulu
354
+ * var sTimezone = "America/New_York";
355
+ * var oDate = new Date("2021-11-13T13:22:33Z");
356
+ *
357
+ * // Show (default)
358
+ * DateFormat.getDateTimeWithTimezoneInstance({showTimezone: "Show"}).format(oDate, false, sTimezone);
359
+ * // Result: "Nov 13, 2021, 8:22:33 AM America/New_York"
360
+ *
361
+ * // Hide
362
+ * DateFormat.getDateTimeWithTimezoneInstance({showTimezone: "Hide"}).format(oDate, false, sTimezone);
363
+ * // Result: "Nov 13, 2021, 8:22:33 AM"
364
+ *
365
+ * // Only
366
+ * DateFormat.getDateTimeWithTimezoneInstance({showTimezone: "Only"}).format(oDate, false, sTimezone);
367
+ * // Result: "America/New_York"
368
+ *
369
+ * @param {object} [oFormatOptions] An object which defines the format options
370
+ * @param {string} [oFormatOptions.format] A string containing pattern symbols (e.g. "yMMMd" or "Hms") which will be converted into a pattern for the used locale that matches the wanted symbols best.
371
+ * The symbols must be in canonical order, that is: Era (G), Year (y/Y), Quarter (q/Q), Month (M/L), Week (w), Day-Of-Week (E/e/c), Day (d), Hour (h/H/k/K/j/J), Minute (m), Second (s), Timezone (z/Z/v/V/O/X/x)
372
+ * See http://unicode.org/reports/tr35/tr35-dates.html#availableFormats_appendItems
373
+ * @param {string} [oFormatOptions.pattern] a datetime pattern in LDML format. It is not verified whether the pattern represents a full datetime.
374
+ * @param {sap.ui.core.format.DateFormatTimezoneDisplay} [oFormatOptions.showTimezone="Show"] Specifies the display of the timezone:
375
+ * <ul>
376
+ * <li>"Show": display both datetime and timezone</li>
377
+ * <li>"Hide": display only datetime</li>
378
+ * <li>"Only": display only timezone</li>
379
+ * </ul>
380
+ * It is ignored for formatting when an options pattern or a format are supplied.
381
+ * @param {string} [oFormatOptions.style] Can be either 'short, 'medium', 'long' or 'full'. For datetime you can also define mixed styles, separated with a slash, where the first part is the date style and the second part is the time style (e.g. "medium/short"). If no pattern is given, a locale-dependent default datetime pattern of that style from the LocaleData class is used.
382
+ * @param {boolean} [oFormatOptions.strictParsing] Whether to check by parsing if the value is a valid datetime
383
+ * @param {boolean} [oFormatOptions.relative] Whether the date is formatted relatively to today's date if it is within the given day range, e.g. "today", "yesterday", "in 5 days"
384
+ * @param {int[]} [oFormatOptions.relativeRange] The day range used for relative formatting. If <code>oFormatOptions.relativeScale</code> is set to the default value 'day', the <code>relativeRange<code> is by default [-6, 6], which means that only the previous 6 and the following 6 days are formatted relatively. If <code>oFormatOptions.relativeScale</code> is set to 'auto', all dates are formatted relatively.
385
+ * @param {string} [oFormatOptions.relativeScale="day"] If 'auto' is set, a new relative time format is switched on for all Date/Time instances.
386
+ * @param {string} [oFormatOptions.relativeStyle="wide"] The style of the relative format. The valid values are "wide", "short", "narrow"
387
+ * @param {sap.ui.core.CalendarType} [oFormatOptions.calendarType] The calendar type which is used to format and parse the date. This value is by default either set in the configuration or calculated based on the current locale.
388
+ * @param {sap.ui.core.Locale} [oLocale] Locale to ask for locale-specific texts/settings
389
+ * @return {sap.ui.core.format.DateFormat.DateTimeWithTimezone} dateTimeWithTimezone instance of the DateFormat
390
+ * @static
391
+ * @public
392
+ * @since 1.99.0
393
+ */
394
+ DateFormat.getDateTimeWithTimezoneInstance = function(oFormatOptions, oLocale) {
395
+ return this.createInstance(oFormatOptions, oLocale, this.oDateTimeWithTimezoneInfo);
396
+ };
397
+
197
398
  /**
198
399
  * Get a time instance of the DateFormat, which can be used for formatting.
199
400
  *
@@ -260,6 +461,18 @@ sap.ui.define([
260
461
  // from the LocaleData, in case it is not defined yet
261
462
  oFormat.oFormatOptions = extend({}, oInfo.oDefaultFormatOptions, oFormatOptions);
262
463
 
464
+ // set unsupported properties to false/undefined
465
+ if (oInfo.type === mDateFormatTypes.DATETIME_WITH_TIMEZONE) {
466
+ oFormat.oFormatOptions.interval = false;
467
+ oFormat.oFormatOptions.singleIntervalValue = false;
468
+ oFormat.oFormatOptions.UTC = false;
469
+ } else {
470
+ oFormat.oFormatOptions.showTimezone = undefined;
471
+ }
472
+
473
+ // type cannot be changed and should be an instance property instead of a format option
474
+ oFormat.type = oInfo.type;
475
+
263
476
  if (!oFormat.oFormatOptions.calendarType) {
264
477
  oFormat.oFormatOptions.calendarType = sap.ui.getCore().getConfiguration().getCalendarType();
265
478
  }
@@ -268,7 +481,7 @@ sap.ui.define([
268
481
  if (oFormat.oFormatOptions.format) {
269
482
  oFormat.oFormatOptions.pattern = oFormat.oLocaleData.getCustomDateTimePattern(oFormat.oFormatOptions.format, oFormat.oFormatOptions.calendarType);
270
483
  } else {
271
- oFormat.oFormatOptions.pattern = oInfo.getPattern(oFormat.oLocaleData, oFormat.oFormatOptions.style, oFormat.oFormatOptions.calendarType);
484
+ oFormat.oFormatOptions.pattern = oInfo.getPattern(oFormat.oLocaleData, oFormat.oFormatOptions.style, oFormat.oFormatOptions.calendarType, oFormat.oFormatOptions.showTimezone);
272
485
  }
273
486
  }
274
487
 
@@ -325,7 +538,7 @@ sap.ui.define([
325
538
  aFallbackFormatOptions = oInfo.aFallbackFormatOptions;
326
539
  // Add two fallback patterns for locale-dependent short format without delimiters
327
540
  if (oInfo.bShortFallbackFormatOptions) {
328
- sPattern = oInfo.getPattern(oFormat.oLocaleData, "short");
541
+ sPattern = oInfo.getPattern(oFormat.oLocaleData, "short", undefined, oFormat.oFormatOptions.showTimezone);
329
542
  // add the options of fallback formats without delimiters to the fallback options array
330
543
  aFallbackFormatOptions = aFallbackFormatOptions.concat(DateFormat._createFallbackOptionsWithoutDelimiter(sPattern));
331
544
  }
@@ -336,7 +549,9 @@ sap.ui.define([
336
549
  aFallbackFormatOptions = DateFormat._createFallbackOptionsWithoutDelimiter(oFormat.oFormatOptions.pattern).concat(aFallbackFormatOptions);
337
550
  }
338
551
 
339
- oFallbackFormats = DateFormat._createFallbackFormat(aFallbackFormatOptions, sCalendarType, oLocale, oInfo, oFormat.oFormatOptions.interval);
552
+ oFallbackFormats = DateFormat._createFallbackFormat(
553
+ aFallbackFormatOptions, sCalendarType, oLocale, oInfo, oFormat.oFormatOptions.interval, oFormat.oFormatOptions.showTimezone
554
+ );
340
555
  }
341
556
 
342
557
  oFormat.aFallbackFormats = oFallbackFormats;
@@ -389,20 +604,32 @@ sap.ui.define([
389
604
  * Creates DateFormat instances based on the given format options. The created
390
605
  * instances are used as fallback formats of another DateFormat instances.
391
606
  *
392
- * All fallback formats are marked with 'bIsFallback' to make it distinguishable
607
+ * All fallback format instances are marked with 'bIsFallback' to make it distinguishable
393
608
  * from the normal DateFormat instances.
394
609
  *
395
610
  * @param {Object[]} aFallbackFormatOptions the options for creating the fallback DateFormat
396
611
  * @param {sap.ui.core.CalendarType} sCalendarType the type of the current calendarType
397
612
  * @param {sap.ui.core.LocaleData} oLocale Locale to ask for locale specific texts/settings
398
613
  * @param {Object} oInfo The default info object of the current date type
614
+ * @param {boolean} bInterval Is an interval
615
+ * @param {sap.ui.core.format.DateFormatTimezoneDisplay} sShowTimezone The showTimezone format option
399
616
  * @return {sap.ui.core.DateFormat[]} an array of fallback DateFormat instances
400
617
  */
401
- DateFormat._createFallbackFormat = function(aFallbackFormatOptions, sCalendarType, oLocale, oInfo, bInterval) {
618
+ DateFormat._createFallbackFormat = function(aFallbackFormatOptions, sCalendarType, oLocale, oInfo, bInterval, sShowTimezone) {
402
619
  return aFallbackFormatOptions.map(function(oOptions) {
403
620
  // The format options within the aFallbackFormatOptions array are static
404
621
  // and shouldn't be manipulated. Hence, cloning each format option is required.
405
622
  var oFormatOptions = Object.assign({}, oOptions);
623
+
624
+ // Pass the showTimezone format option to the fallback instance.
625
+ oFormatOptions.showTimezone = sShowTimezone;
626
+
627
+ // the timezone instance's fallback patterns depend on the showTimezone format option which means they cannot be static,
628
+ // therefore they are generated using the getTimezonePattern function
629
+ if (typeof oInfo.getTimezonePattern === "function" && oFormatOptions.pattern) {
630
+ oFormatOptions.pattern = oInfo.getTimezonePattern(oFormatOptions.pattern, sShowTimezone);
631
+ }
632
+
406
633
  if (bInterval) {
407
634
  oFormatOptions.interval = true;
408
635
  }
@@ -487,7 +714,7 @@ sap.ui.define([
487
714
  *
488
715
  * @param {string} sValue, e.g. "-0800", "-08:00", "-08"
489
716
  * @param {boolean} bColonSeparated whether or not the values are colon separated, e.g. "-08:00"
490
- * @returns {{tzDiff: number, length: number}}
717
+ * @returns {{tzDiff: number, length: number}} object containing the timezone difference in seconds and the length of the parsed segment
491
718
  */
492
719
  parseTZ: function (sValue, bColonSeparated) {
493
720
  var iLength = 0;
@@ -513,7 +740,7 @@ sap.ui.define([
513
740
 
514
741
  return {
515
742
  length: iLength,
516
- tzDiff: (iTZDiff + 60 * iTZDiffHour) * iTZFactor
743
+ tzDiff: (iTZDiff + 60 * iTZDiffHour) * 60 * iTZFactor
517
744
  };
518
745
  },
519
746
 
@@ -530,7 +757,7 @@ sap.ui.define([
530
757
  DateFormat.prototype.oSymbols = {
531
758
  "": {
532
759
  name: "text",
533
- format: function(oField, oDate, bUTC, oFormat) {
760
+ format: function(oField, oDate) {
534
761
  return oField.value;
535
762
  },
536
763
  parse: function(sValue, oPart, oFormat, oConfig) {
@@ -591,7 +818,7 @@ sap.ui.define([
591
818
  "G": {
592
819
  name: "era",
593
820
  format: function(oField, oDate, bUTC, oFormat) {
594
- var iEra = bUTC ? oDate.getUTCEra() : oDate.getEra();
821
+ var iEra = oDate.getUTCEra();
595
822
  if (oField.digits <= 3) {
596
823
  return oFormat.aErasAbbrev[iEra];
597
824
  } else if (oField.digits === 4) {
@@ -622,7 +849,7 @@ sap.ui.define([
622
849
  "y": {
623
850
  name: "year",
624
851
  format: function(oField, oDate, bUTC, oFormat) {
625
- var iYear = bUTC ? oDate.getUTCFullYear() : oDate.getFullYear();
852
+ var iYear = oDate.getUTCFullYear();
626
853
  var sYear = String(iYear);
627
854
  var sCalendarType = oFormat.oFormatOptions.calendarType;
628
855
 
@@ -668,7 +895,7 @@ sap.ui.define([
668
895
  // 2018: 47 = 2047 (diff: 29)
669
896
  if (sCalendarType != CalendarType.Japanese && sPart.length <= 2) {
670
897
  var oCurrentDate = UniversalDate.getInstance(new Date(), sCalendarType),
671
- iCurrentYear = oCurrentDate.getFullYear(),
898
+ iCurrentYear = oCurrentDate.getUTCFullYear(),
672
899
  iCurrentCentury = Math.floor(iCurrentYear / 100),
673
900
  iYearDiff = iCurrentCentury * 100 + iYear - iCurrentYear;
674
901
  if (iYearDiff < -70) {
@@ -689,7 +916,7 @@ sap.ui.define([
689
916
  "Y": {
690
917
  name: "weekYear",
691
918
  format: function(oField, oDate, bUTC, oFormat) {
692
- var oWeek = bUTC ? oDate.getUTCWeek() : oDate.getWeek();
919
+ var oWeek = oDate.getUTCWeek();
693
920
  var iWeekYear = oWeek.year;
694
921
  var sWeekYear = String(iWeekYear);
695
922
  var sCalendarType = oFormat.oFormatOptions.calendarType;
@@ -719,7 +946,7 @@ sap.ui.define([
719
946
  // Find the right century for two-digit years
720
947
  if (sCalendarType != CalendarType.Japanese && sPart.length <= 2) {
721
948
  var oCurrentDate = UniversalDate.getInstance(new Date(), sCalendarType),
722
- iCurrentYear = oCurrentDate.getFullYear(),
949
+ iCurrentYear = oCurrentDate.getUTCFullYear(),
723
950
  iCurrentCentury = Math.floor(iCurrentYear / 100),
724
951
  iYearDiff = iCurrentCentury * 100 + iWeekYear - iCurrentYear;
725
952
  if (iYearDiff < -70) {
@@ -741,7 +968,7 @@ sap.ui.define([
741
968
  "M": {
742
969
  name: "month",
743
970
  format: function(oField, oDate, bUTC, oFormat) {
744
- var iMonth = bUTC ? oDate.getUTCMonth() : oDate.getMonth();
971
+ var iMonth = oDate.getUTCMonth();
745
972
  if (oField.digits == 3) {
746
973
  return oFormat.aMonthsAbbrev[iMonth];
747
974
  } else if (oField.digits == 4) {
@@ -788,7 +1015,7 @@ sap.ui.define([
788
1015
  "L": {
789
1016
  name: "monthStandalone",
790
1017
  format: function(oField, oDate, bUTC, oFormat) {
791
- var iMonth = bUTC ? oDate.getUTCMonth() : oDate.getMonth();
1018
+ var iMonth = oDate.getUTCMonth();
792
1019
  if (oField.digits == 3) {
793
1020
  return oFormat.aMonthsAbbrevSt[iMonth];
794
1021
  } else if (oField.digits == 4) {
@@ -835,7 +1062,7 @@ sap.ui.define([
835
1062
  "w": {
836
1063
  name: "weekInYear",
837
1064
  format: function(oField, oDate, bUTC, oFormat) {
838
- var oWeek = bUTC ? oDate.getUTCWeek() : oDate.getWeek();
1065
+ var oWeek = oDate.getUTCWeek();
839
1066
  var iWeek = oWeek.week;
840
1067
  var sWeek = String(iWeek + 1);
841
1068
  if (oField.digits < 3) {
@@ -858,12 +1085,14 @@ sap.ui.define([
858
1085
  bValid = oParseHelper.checkValid(oPart.type, !sPart, oFormat);
859
1086
  } else {
860
1087
  sPart = oFormat.oLocaleData.getCalendarWeek(oPart.digits === 3 ? "narrow" : "wide");
861
- sPart = sPart.replace("{0}", "[0-9]+");
1088
+ sPart = sPart.replace("{0}", "([0-9]+)");
862
1089
  var rWeekNumber = new RegExp(sPart),
863
1090
  oResult = rWeekNumber.exec(sValue);
864
1091
  if (oResult) {
1092
+ // e.g. for input "CW 01" create pattern "CW ([0-9]+)"
1093
+ // and extract number from "01" part of the input
865
1094
  iLength = oResult[0].length;
866
- iWeek = parseInt(oResult[0]) - 1;
1095
+ iWeek = parseInt(oResult[oResult.length - 1]) - 1;
867
1096
  } else {
868
1097
  bValid = oParseHelper.checkValid(oPart.type, true, oFormat);
869
1098
  }
@@ -878,7 +1107,7 @@ sap.ui.define([
878
1107
  },
879
1108
  "W": {
880
1109
  name: "weekInMonth",
881
- format: function(oField, oDate, bUTC, oFormat) {
1110
+ format: function(oField, oDate) {
882
1111
  // not supported
883
1112
  return "";
884
1113
  },
@@ -888,7 +1117,7 @@ sap.ui.define([
888
1117
  },
889
1118
  "D": {
890
1119
  name: "dayInYear",
891
- format: function(oField, oDate, bUTC, oFormat) {
1120
+ format: function(oField, oDate) {
892
1121
 
893
1122
  },
894
1123
  parse: function() {
@@ -897,8 +1126,8 @@ sap.ui.define([
897
1126
  },
898
1127
  "d": {
899
1128
  name: "day",
900
- format: function(oField, oDate, bUTC, oFormat) {
901
- var iDate = bUTC ? oDate.getUTCDate() : oDate.getDate();
1129
+ format: function(oField, oDate) {
1130
+ var iDate = oDate.getUTCDate();
902
1131
  return String(iDate).padStart(oField.digits, "0");
903
1132
  },
904
1133
  parse: function(sValue, oPart, oFormat, oConfig) {
@@ -918,7 +1147,7 @@ sap.ui.define([
918
1147
  "Q": {
919
1148
  name: "quarter",
920
1149
  format: function(oField, oDate, bUTC, oFormat) {
921
- var iQuarter = bUTC ? oDate.getUTCQuarter() : oDate.getQuarter();
1150
+ var iQuarter = oDate.getUTCQuarter();
922
1151
  if (oField.digits == 3) {
923
1152
  return oFormat.aQuartersAbbrev[iQuarter];
924
1153
  } else if (oField.digits == 4) {
@@ -966,7 +1195,7 @@ sap.ui.define([
966
1195
  "q": {
967
1196
  name: "quarterStandalone",
968
1197
  format: function(oField, oDate, bUTC, oFormat) {
969
- var iQuarter = bUTC ? oDate.getUTCQuarter() : oDate.getQuarter();
1198
+ var iQuarter = oDate.getUTCQuarter();
970
1199
  if (oField.digits == 3) {
971
1200
  return oFormat.aQuartersAbbrevSt[iQuarter];
972
1201
  } else if (oField.digits == 4) {
@@ -1013,7 +1242,7 @@ sap.ui.define([
1013
1242
  },
1014
1243
  "F": {
1015
1244
  name: "dayOfWeekInMonth",
1016
- format: function(oField, oDate, bUTC, oFormat) {
1245
+ format: function(oField, oDate, oFormat) {
1017
1246
  // not supported
1018
1247
  return "";
1019
1248
  },
@@ -1024,7 +1253,7 @@ sap.ui.define([
1024
1253
  "E": {
1025
1254
  name: "dayNameInWeek", //Day of week name, format style.
1026
1255
  format: function(oField, oDate, bUTC, oFormat) {
1027
- var iDay = bUTC ? oDate.getUTCDay() : oDate.getDay();
1256
+ var iDay = oDate.getUTCDay();
1028
1257
  if (oField.digits < 4) {
1029
1258
  return oFormat.aDaysAbbrev[iDay];
1030
1259
  } else if (oField.digits == 4) {
@@ -1054,7 +1283,7 @@ sap.ui.define([
1054
1283
  "c": {
1055
1284
  name: "dayNameInWeekStandalone",
1056
1285
  format: function(oField, oDate, bUTC, oFormat) {
1057
- var iDay = bUTC ? oDate.getUTCDay() : oDate.getDay();
1286
+ var iDay = oDate.getUTCDay();
1058
1287
  if (oField.digits < 4) {
1059
1288
  return oFormat.aDaysAbbrevSt[iDay];
1060
1289
  } else if (oField.digits == 4) {
@@ -1083,7 +1312,7 @@ sap.ui.define([
1083
1312
  "u": {
1084
1313
  name: "dayNumberOfWeek",
1085
1314
  format: function(oField, oDate, bUTC, oFormat) {
1086
- var iDay = bUTC ? oDate.getUTCDay() : oDate.getDay();
1315
+ var iDay = oDate.getUTCDay();
1087
1316
  return oFormat._adaptDayOfWeek(iDay);
1088
1317
  },
1089
1318
  parse: function(sValue, oPart, oFormat, oConfig) {
@@ -1098,7 +1327,7 @@ sap.ui.define([
1098
1327
  "a": {
1099
1328
  name: "amPmMarker",
1100
1329
  format: function(oField, oDate, bUTC, oFormat) {
1101
- var iDayPeriod = bUTC ? oDate.getUTCDayPeriod() : oDate.getDayPeriod();
1330
+ var iDayPeriod = oDate.getUTCDayPeriod();
1102
1331
 
1103
1332
  return oFormat.aDayPeriods[iDayPeriod];
1104
1333
  },
@@ -1144,8 +1373,8 @@ sap.ui.define([
1144
1373
  },
1145
1374
  "H": {
1146
1375
  name: "hour0_23",
1147
- format: function(oField, oDate, bUTC, oFormat) {
1148
- var iHours = bUTC ? oDate.getUTCHours() : oDate.getHours();
1376
+ format: function(oField, oDate) {
1377
+ var iHours = oDate.getUTCHours();
1149
1378
  return String(iHours).padStart(oField.digits, "0");
1150
1379
  },
1151
1380
  parse: function(sValue, oPart, oFormat, oConfig) {
@@ -1168,8 +1397,8 @@ sap.ui.define([
1168
1397
  },
1169
1398
  "k": {
1170
1399
  name: "hour1_24",
1171
- format: function(oField, oDate, bUTC, oFormat) {
1172
- var iHours = bUTC ? oDate.getUTCHours() : oDate.getHours();
1400
+ format: function(oField, oDate) {
1401
+ var iHours = oDate.getUTCHours();
1173
1402
  var sHours = (iHours === 0 ? "24" : String(iHours));
1174
1403
 
1175
1404
  return sHours.padStart(oField.digits, "0");
@@ -1197,8 +1426,8 @@ sap.ui.define([
1197
1426
  },
1198
1427
  "K": {
1199
1428
  name: "hour0_11",
1200
- format: function(oField, oDate, bUTC, oFormat) {
1201
- var iHours = bUTC ? oDate.getUTCHours() : oDate.getHours();
1429
+ format: function(oField, oDate) {
1430
+ var iHours = oDate.getUTCHours();
1202
1431
  var sHours = String(iHours > 11 ? iHours - 12 : iHours);
1203
1432
 
1204
1433
  return sHours.padStart(oField.digits, "0");
@@ -1223,8 +1452,8 @@ sap.ui.define([
1223
1452
  },
1224
1453
  "h": {
1225
1454
  name: "hour1_12",
1226
- format: function(oField, oDate, bUTC, oFormat) {
1227
- var iHours = bUTC ? oDate.getUTCHours() : oDate.getHours();
1455
+ format: function(oField, oDate) {
1456
+ var iHours = oDate.getUTCHours();
1228
1457
  var sHours;
1229
1458
 
1230
1459
  if (iHours > 12) {
@@ -1264,8 +1493,8 @@ sap.ui.define([
1264
1493
  },
1265
1494
  "m": {
1266
1495
  name: "minute",
1267
- format: function(oField, oDate, bUTC, oFormat) {
1268
- var iMinutes = bUTC ? oDate.getUTCMinutes() : oDate.getMinutes();
1496
+ format: function(oField, oDate) {
1497
+ var iMinutes = oDate.getUTCMinutes();
1269
1498
  return String(iMinutes).padStart(oField.digits, "0");
1270
1499
  },
1271
1500
  parse: function(sValue, oPart, oFormat, oConfig) {
@@ -1288,8 +1517,8 @@ sap.ui.define([
1288
1517
  },
1289
1518
  "s": {
1290
1519
  name: "second",
1291
- format: function(oField, oDate, bUTC, oFormat) {
1292
- var iSeconds = bUTC ? oDate.getUTCSeconds() : oDate.getSeconds();
1520
+ format: function(oField, oDate) {
1521
+ var iSeconds = oDate.getUTCSeconds();
1293
1522
  return String(iSeconds).padStart(oField.digits, "0");
1294
1523
  },
1295
1524
  parse: function(sValue, oPart, oFormat, oConfig) {
@@ -1312,8 +1541,8 @@ sap.ui.define([
1312
1541
  },
1313
1542
  "S": {
1314
1543
  name: "fractionalsecond",
1315
- format: function(oField, oDate, bUTC, oFormat) {
1316
- var iMilliseconds = bUTC ? oDate.getUTCMilliseconds() : oDate.getMilliseconds();
1544
+ format: function(oField, oDate) {
1545
+ var iMilliseconds = oDate.getUTCMilliseconds();
1317
1546
  var sMilliseconds = String(iMilliseconds);
1318
1547
  var sFractionalseconds = sMilliseconds.padStart(3, "0");
1319
1548
  sFractionalseconds = sFractionalseconds.substr(0, oField.digits);
@@ -1337,7 +1566,7 @@ sap.ui.define([
1337
1566
  },
1338
1567
  "z": {
1339
1568
  name: "timezoneGeneral",
1340
- format: function(oField, oDate, bUTC, oFormat) {
1569
+ format: function(oField, oDate, bUTC, oFormat, sTimezone) {
1341
1570
  //TODO getTimezoneLong and getTimezoneShort does not exist on Date object
1342
1571
  //-> this is a preparation for a future full timezone support (only used by unit test so far)
1343
1572
  if (oField.digits > 3 && oDate.getTimezoneLong && oDate.getTimezoneLong()) {
@@ -1347,12 +1576,12 @@ sap.ui.define([
1347
1576
  }
1348
1577
 
1349
1578
  // valid for zzzz (fallback to OOOO)
1350
-
1579
+ var iTimezoneOffset = TimezoneUtil.calculateOffset(oDate, sTimezone);
1351
1580
  var sTimeZone = "GMT";
1352
- var iTZOffset = Math.abs(oDate.getTimezoneOffset());
1353
- var bPositiveOffset = oDate.getTimezoneOffset() > 0;
1581
+ var iTZOffset = Math.abs(iTimezoneOffset / 60);
1582
+ var bPositiveOffset = iTimezoneOffset > 0;
1354
1583
  var iHourOffset = Math.floor(iTZOffset / 60);
1355
- var iMinuteOffset = iTZOffset % 60;
1584
+ var iMinuteOffset = Math.floor(iTZOffset % 60);
1356
1585
 
1357
1586
  if (!bUTC && iTZOffset != 0) {
1358
1587
  sTimeZone += (bPositiveOffset ? "-" : "+");
@@ -1398,11 +1627,12 @@ sap.ui.define([
1398
1627
  },
1399
1628
  "Z": {
1400
1629
  name: "timezoneRFC822",
1401
- format: function(oField, oDate, bUTC, oFormat) {
1402
- var iTZOffset = Math.abs(oDate.getTimezoneOffset());
1403
- var bPositiveOffset = oDate.getTimezoneOffset() > 0;
1630
+ format: function(oField, oDate, bUTC, oFormat, sTimezone) {
1631
+ var iTimezoneOffset = TimezoneUtil.calculateOffset(oDate, sTimezone);
1632
+ var iTZOffset = Math.abs(iTimezoneOffset / 60);
1633
+ var bPositiveOffset = iTimezoneOffset > 0;
1404
1634
  var iHourOffset = Math.floor(iTZOffset / 60);
1405
- var iMinuteOffset = iTZOffset % 60;
1635
+ var iMinuteOffset = Math.floor(iTZOffset % 60);
1406
1636
  var sTimeZone = "";
1407
1637
 
1408
1638
  // valid for Z-ZZZ
@@ -1425,7 +1655,7 @@ sap.ui.define([
1425
1655
  },
1426
1656
  "X": {
1427
1657
  name: "timezoneISO8601",
1428
- format: function(oField, oDate, bUTC, oFormat) {
1658
+ format: function(oField, oDate, bUTC, oFormat, sTimezone) {
1429
1659
  /*
1430
1660
  * Mountain Standard Time (MST, UTC-7)
1431
1661
  * X: "-07"
@@ -1455,10 +1685,11 @@ sap.ui.define([
1455
1685
  */
1456
1686
 
1457
1687
  // @see http://www.unicode.org/reports/tr35/tr35-dates.html#Time_Zone_Goals
1458
- var iTZOffset = Math.abs(oDate.getTimezoneOffset());
1459
- var bPositiveOffset = oDate.getTimezoneOffset() > 0;
1688
+ var iTimezoneOffset = TimezoneUtil.calculateOffset(oDate, sTimezone);
1689
+ var iTZOffset = Math.abs(iTimezoneOffset / 60);
1690
+ var bPositiveOffset = iTimezoneOffset > 0;
1460
1691
  var iHourOffset = Math.floor(iTZOffset / 60);
1461
- var iMinuteOffset = iTZOffset % 60;
1692
+ var iMinuteOffset = Math.floor(iTZOffset % 60);
1462
1693
 
1463
1694
  var sTimeZone = "";
1464
1695
  if (!bUTC && iTZOffset != 0) {
@@ -1486,12 +1717,53 @@ sap.ui.define([
1486
1717
  return oParseHelper.parseTZ(sValue, oPart.digits === 3 || oPart.digits === 5);
1487
1718
  }
1488
1719
  }
1720
+ },
1721
+ "V": {
1722
+ name: "timezoneID",
1723
+ format: function(oField, oDate, bUTC, oFormat, sTimezone) {
1724
+ // Only VV is supported
1725
+ // The IANA timezone ID
1726
+ // e.g. America/New_York
1727
+ // @see http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns
1728
+ if (!bUTC && oField.digits === 2) {
1729
+ return sTimezone;
1730
+ }
1731
+ return "";
1732
+ },
1733
+ parse: function(sValue, oPart, oFormat, oConfig, sTimezone) {
1734
+ var oTimezoneParsed = {
1735
+ timezone: "",
1736
+ length: 0
1737
+ };
1738
+
1739
+ // VV - The long IANA timezone ID
1740
+ if (oPart.digits === 2) {
1741
+ if (sValue === sTimezone) {
1742
+ oTimezoneParsed.timezone = sTimezone;
1743
+ oTimezoneParsed.length = sTimezone.length;
1744
+ return oTimezoneParsed;
1745
+ }
1746
+
1747
+ // TODO: Support more pattern in regex like UTC or without the country part, checking for valid timezone
1748
+ if (sValue) {
1749
+ var rIanaTimezone = new RegExp("([A-Za-z_])+([\/][A-Za-z_]+)+");
1750
+ var aResult = rIanaTimezone.exec(sValue);
1751
+ if (aResult && aResult[0] && TimezoneUtil.isValidTimezone(aResult[0])) {
1752
+ oTimezoneParsed.timezone = aResult[0];
1753
+ oTimezoneParsed.length = aResult[0].length;
1754
+ return oTimezoneParsed;
1755
+ }
1756
+ }
1757
+ }
1758
+
1759
+ return oTimezoneParsed;
1760
+ }
1489
1761
  }
1490
1762
  };
1491
1763
 
1492
- DateFormat.prototype._format = function(oJSDate, bUTC) {
1764
+ DateFormat.prototype._format = function(oJSDate, bUTC, sTimezone) {
1493
1765
  if (this.oFormatOptions.relative) {
1494
- var sRes = this.formatRelative(oJSDate, bUTC, this.oFormatOptions.relativeRange);
1766
+ var sRes = this.formatRelative(oJSDate, bUTC, this.oFormatOptions.relativeRange, sTimezone);
1495
1767
  if (sRes) { //Stop when relative formatting possible, else go on with standard formatting
1496
1768
  return sRes;
1497
1769
  }
@@ -1506,7 +1778,7 @@ sap.ui.define([
1506
1778
  oPart = this.aFormatArray[i];
1507
1779
  sSymbol = oPart.symbol || "";
1508
1780
 
1509
- aBuffer.push(this.oSymbols[sSymbol].format(oPart, oDate, bUTC, this));
1781
+ aBuffer.push(this.oSymbols[sSymbol].format(oPart, oDate, bUTC, this, sTimezone));
1510
1782
  }
1511
1783
 
1512
1784
  sResult = aBuffer.join("");
@@ -1529,12 +1801,33 @@ sap.ui.define([
1529
1801
  /**
1530
1802
  * Format a date according to the given format options.
1531
1803
  *
1804
+ * Uses the timezone from {@link sap.ui.core.Configuration#getTimezone}, which falls back to the
1805
+ * browser's local timezone to convert the given date.
1806
+ *
1807
+ * @example <caption>DateTime (with timezone "Europe/Berlin")</caption>
1808
+ * var oDate = new Date(Date.UTC(2021, 11, 24, 13, 37));
1809
+ * DateFormat.getDateTimeInstance().format(oDate);
1810
+ * // output: "Dec 24, 2021, 2:37:00 PM"
1811
+ *
1532
1812
  * @param {Date|Date[]} vJSDate the value to format
1533
1813
  * @param {boolean} [bUTC=false] whether to use UTC
1534
1814
  * @return {string} the formatted output value. If an invalid date is given, an empty string is returned.
1535
1815
  * @public
1536
1816
  */
1537
1817
  DateFormat.prototype.format = function(vJSDate, bUTC) {
1818
+ var sTimezone;
1819
+ if (this.type === mDateFormatTypes.DATETIME_WITH_TIMEZONE) {
1820
+ // UTC and timezone are not supported at the same time, therefore set bUTC to false
1821
+ sTimezone = bUTC;
1822
+ bUTC = false;
1823
+
1824
+ // timezone is required to calculate the timezone offset therefore it must be a valid IANA timezone ID
1825
+ if (sTimezone != null && !TimezoneUtil.isValidTimezone(sTimezone)) {
1826
+ Log.error("The given timezone isn't valid.");
1827
+ return "";
1828
+ }
1829
+ }
1830
+
1538
1831
  var sCalendarType = this.oFormatOptions.calendarType,
1539
1832
  sResult;
1540
1833
 
@@ -1542,6 +1835,9 @@ sap.ui.define([
1542
1835
  bUTC = this.oFormatOptions.UTC;
1543
1836
  }
1544
1837
 
1838
+ // default the timezone to the local timezone to always enforce the conversion
1839
+ sTimezone = sTimezone || sap.ui.getCore().getConfiguration().getTimezone();
1840
+
1545
1841
  if (Array.isArray(vJSDate)) {
1546
1842
  if (!this.oFormatOptions.interval) {
1547
1843
  Log.error("Non-interval DateFormat can't format more than one date instance.");
@@ -1552,6 +1848,12 @@ sap.ui.define([
1552
1848
  Log.error("Interval DateFormat can only format with 2 date instances but " + vJSDate.length + " is given.");
1553
1849
  return "";
1554
1850
  }
1851
+ vJSDate = vJSDate.map(function(oJSDate) {
1852
+ if (oJSDate && !isNaN(oJSDate.getTime())) {
1853
+ return convertToTimezone(oJSDate, sTimezone, bUTC);
1854
+ }
1855
+ return oJSDate;
1856
+ });
1555
1857
 
1556
1858
  if (this.oFormatOptions.singleIntervalValue) {
1557
1859
  if (vJSDate[0] === null) {
@@ -1560,7 +1862,7 @@ sap.ui.define([
1560
1862
  }
1561
1863
 
1562
1864
  if (vJSDate[1] === null) {
1563
- sResult = this._format(vJSDate[0], bUTC);
1865
+ sResult = this._format(vJSDate[0], bUTC, sTimezone);
1564
1866
  }
1565
1867
  }
1566
1868
 
@@ -1578,6 +1880,11 @@ sap.ui.define([
1578
1880
  }
1579
1881
  } else {
1580
1882
  if (!vJSDate || isNaN(vJSDate.getTime())) {
1883
+ // Although an invalid date was given, the DATETIME_WITH_TIMEZONE instance might
1884
+ // have a pattern with the timezone (VV) inside then the IANA timezone ID is returned
1885
+ if (this.type === mDateFormatTypes.DATETIME_WITH_TIMEZONE && this.oFormatOptions.pattern.includes("VV")) {
1886
+ return sTimezone;
1887
+ }
1581
1888
  Log.error("The given date instance isn't valid.");
1582
1889
  return "";
1583
1890
  }
@@ -1587,7 +1894,8 @@ sap.ui.define([
1587
1894
  return "";
1588
1895
  }
1589
1896
 
1590
- sResult = this._format(vJSDate, bUTC);
1897
+ vJSDate = convertToTimezone(vJSDate, sTimezone, bUTC);
1898
+ sResult = this._format(vJSDate, bUTC, sTimezone);
1591
1899
  }
1592
1900
 
1593
1901
  // Support Japanese Gannen instead of Ichinen for first year of the era
@@ -1609,7 +1917,7 @@ sap.ui.define([
1609
1917
  var sPattern;
1610
1918
  var aFormatArray = [];
1611
1919
 
1612
- var oDiffField = this._getGreatestDiffField([oFromDate, oToDate], bUTC);
1920
+ var oDiffField = this._getGreatestDiffField([oFromDate, oToDate]);
1613
1921
 
1614
1922
  if (!oDiffField) {
1615
1923
  return this._format(aJSDates[0], bUTC);
@@ -1653,12 +1961,13 @@ sap.ui.define([
1653
1961
  Seconds: "Second"
1654
1962
  };
1655
1963
 
1656
- DateFormat.prototype._getGreatestDiffField = function(aDates, bUTC) {
1964
+ // the expected dates are UTC and therefore their UTC functions are called, e.g. getUTCHours
1965
+ DateFormat.prototype._getGreatestDiffField = function(aDates) {
1657
1966
  var bDiffFound = false,
1658
1967
  mDiff = {};
1659
1968
 
1660
1969
  this.aIntervalCompareFields.forEach(function(sField) {
1661
- var sGetterPrefix = "get" + (bUTC ? "UTC" : ""),
1970
+ var sGetterPrefix = "getUTC",
1662
1971
  sMethodName = sGetterPrefix + sField,
1663
1972
  sFieldGroup = mFieldToGroup[sField],
1664
1973
  vFromValue = aDates[0][sMethodName].apply(aDates[0]),
@@ -1677,12 +1986,13 @@ sap.ui.define([
1677
1986
  return null;
1678
1987
  };
1679
1988
 
1680
- DateFormat.prototype._parse = function(sValue, aFormatArray, bUTC, bStrict) {
1989
+ DateFormat.prototype._parse = function(sValue, aFormatArray, bUTC, bStrict, sTimezone) {
1681
1990
  var iIndex = 0,
1682
1991
  oPart, sSubValue, oResult;
1683
1992
 
1684
1993
  var oDateValue = {
1685
- valid: true
1994
+ valid: true,
1995
+ lastTimezonePatternSymbol: ""
1686
1996
  };
1687
1997
 
1688
1998
  var oParseConf = {
@@ -1694,11 +2004,13 @@ sap.ui.define([
1694
2004
  for (var i = 0; i < aFormatArray.length; i++) {
1695
2005
  sSubValue = sValue.substr(iIndex);
1696
2006
  oPart = aFormatArray[i];
1697
-
1698
2007
  oParseConf.index = i;
1699
2008
 
1700
- oResult = this.oSymbols[oPart.symbol || ""].parse(sSubValue, oPart, this, oParseConf) || {} ;
1701
-
2009
+ oResult = this.oSymbols[oPart.symbol || ""].parse(sSubValue, oPart, this, oParseConf, sTimezone) || {};
2010
+ // Remember the last required timezone difference which needs to be calculated (V pattern) or applied (x and z pattern)
2011
+ if (oResult.tzDiff !== undefined || oResult.timezone) {
2012
+ oResult.lastTimezonePatternSymbol = oPart.symbol;
2013
+ }
1702
2014
  oDateValue = extend(oDateValue, oResult);
1703
2015
 
1704
2016
  if (oResult.valid === false) {
@@ -1727,7 +2039,7 @@ sap.ui.define([
1727
2039
  return oDateValue;
1728
2040
  };
1729
2041
 
1730
- DateFormat.prototype._parseInterval = function(sValue, sCalendarType, bUTC, bStrict) {
2042
+ DateFormat.prototype._parseInterval = function(sValue, sCalendarType, bUTC, bStrict, sTimezone) {
1731
2043
  var aDateValues,
1732
2044
  iRepeat,
1733
2045
  oDateValue;
@@ -1747,7 +2059,7 @@ sap.ui.define([
1747
2059
  }
1748
2060
  if (iRepeat === undefined) {
1749
2061
  // In case of standard date pattern, parse string as single date and put the same date twice into the aDateValues array
1750
- oDateValue = this._parse(sValue, aFormatArray, bUTC, bStrict);
2062
+ oDateValue = this._parse(sValue, aFormatArray, bUTC, bStrict, sTimezone);
1751
2063
 
1752
2064
  // If input value has not been completely parsed, mark it as invalid
1753
2065
  if (oDateValue.index === 0 || oDateValue.index < sValue.length) {
@@ -1765,7 +2077,7 @@ sap.ui.define([
1765
2077
  aDateValues = [];
1766
2078
 
1767
2079
  // Call _parse function with start 0 and end index of repeated symbol
1768
- oDateValue = this._parse(sValue, aFormatArray.slice(0, iRepeat), bUTC, bStrict);
2080
+ oDateValue = this._parse(sValue, aFormatArray.slice(0, iRepeat), bUTC, bStrict, sTimezone);
1769
2081
 
1770
2082
  if (oDateValue.valid === false) {
1771
2083
  return;
@@ -1775,7 +2087,7 @@ sap.ui.define([
1775
2087
  var iLength = oDateValue.index;
1776
2088
 
1777
2089
  // Call _parse function with start iRepeat and end of array
1778
- oDateValue = this._parse(sValue.substring(iLength), aFormatArray.slice(iRepeat), bUTC, bStrict);
2090
+ oDateValue = this._parse(sValue.substring(iLength), aFormatArray.slice(iRepeat), bUTC, bStrict, sTimezone);
1779
2091
 
1780
2092
  // If input value has not been completely parsed, mark it as invalid
1781
2093
  if (oDateValue.index === 0 || oDateValue.index + iLength < sValue.length) {
@@ -1794,80 +2106,84 @@ sap.ui.define([
1794
2106
  return aDateValues;
1795
2107
  };
1796
2108
 
2109
+ /**
2110
+ * Converts a given date to the given timezone if bUTC is false
2111
+ *
2112
+ * @param {Date} oJSDate The date which should be converted
2113
+ * @param {string} sTimezone target timezone
2114
+ * @param {boolean} bUTC whether it is utc
2115
+ * @returns {Date} the converted date
2116
+ */
2117
+ var convertToTimezone = function(oJSDate, sTimezone, bUTC) {
2118
+ // Convert to timezone if provided and a valid date is supplied
2119
+ if (!bUTC
2120
+ && oJSDate && !isNaN(oJSDate.getTime())) {
2121
+ // convert given date to a date in the target timezone
2122
+ return TimezoneUtil.convertToTimezone(oJSDate, sTimezone);
2123
+ }
2124
+ return oJSDate;
2125
+ };
2126
+
1797
2127
  // recreate javascript date object from the given oDateValues.
1798
2128
  // In case of oDateValue.valid == false, null value will be returned
1799
- var fnCreateDate = function(oDateValue, sCalendarType, bUTC, bStrict) {
2129
+ var fnCreateDate = function(oDateValue, sCalendarType, bUTC, bStrict, sTimezone) {
2130
+ if (!oDateValue.valid) {
2131
+ return null;
2132
+ }
2133
+
1800
2134
  var oDate,
1801
2135
  iYear = typeof oDateValue.year === "number" ? oDateValue.year : 1970;
1802
2136
 
1803
- if (oDateValue.valid) {
1804
- if (bUTC || oDateValue.tzDiff !== undefined) {
1805
- oDate = UniversalDate.getInstance(new Date(0), sCalendarType);
1806
- oDate.setUTCEra(oDateValue.era || UniversalDate.getCurrentEra(sCalendarType));
1807
- oDate.setUTCFullYear(iYear);
1808
- oDate.setUTCMonth(oDateValue.month || 0);
1809
- oDate.setUTCDate(oDateValue.day || 1);
1810
- oDate.setUTCHours(oDateValue.hour || 0);
1811
- oDate.setUTCMinutes(oDateValue.minute || 0);
1812
- oDate.setUTCSeconds(oDateValue.second || 0);
1813
- oDate.setUTCMilliseconds(oDateValue.millisecond || 0);
1814
- if (bStrict && (oDateValue.day || 1) !== oDate.getUTCDate()) {
1815
- // check if valid date given - if invalid, day is not the same (31.Apr -> 1.May)
1816
- oDateValue.valid = false;
1817
- oDate = undefined;
1818
- } else {
1819
- if (oDateValue.tzDiff) {
1820
- // Set TZDiff after checking for valid day, as it may switch the day as well
1821
- oDate.setUTCMinutes((oDateValue.minute || 0) + oDateValue.tzDiff);
1822
- }
1823
- if (oDateValue.week !== undefined && (oDateValue.month === undefined || oDateValue.day === undefined)) {
1824
- //check that the week is only set if the day/month has not been set, because day/month have higher precedence than week
1825
- oDate.setUTCWeek({
1826
- year: oDateValue.weekYear || oDateValue.year,
1827
- week: oDateValue.week
1828
- });
1829
-
1830
- //add the dayNumberOfWeek to the current day
1831
- if (oDateValue.dayNumberOfWeek !== undefined) {
1832
- oDate.setUTCDate(oDate.getUTCDate() + oDateValue.dayNumberOfWeek - 1);
1833
- }
1834
- }
1835
- }
1836
- } else {
1837
- oDate = UniversalDate.getInstance(new Date(1970, 0, 1, 0, 0, 0), sCalendarType);
1838
- oDate.setEra(oDateValue.era || UniversalDate.getCurrentEra(sCalendarType));
1839
- oDate.setFullYear(iYear);
1840
- oDate.setMonth(oDateValue.month || 0);
1841
- oDate.setDate(oDateValue.day || 1);
1842
- oDate.setHours(oDateValue.hour || 0);
1843
- oDate.setMinutes(oDateValue.minute || 0);
1844
- oDate.setSeconds(oDateValue.second || 0);
1845
- oDate.setMilliseconds(oDateValue.millisecond || 0);
1846
- if (bStrict && (oDateValue.day || 1) !== oDate.getDate()) {
1847
- // check if valid date given - if invalid, day is not the same (31.Apr -> 1.May)
1848
- oDateValue.valid = false;
1849
- oDate = undefined;
1850
- } else if (oDateValue.week !== undefined && (oDateValue.month === undefined || oDateValue.day === undefined)) {
1851
- //check that the week is only set if the day/month has not been set, because day/month have higher precedence than week
1852
- oDate.setWeek({
1853
- year: oDateValue.weekYear || oDateValue.year,
1854
- week: oDateValue.week
1855
- });
1856
-
1857
- //add the dayNumberOfWeek to the current day
1858
- if (oDateValue.dayNumberOfWeek !== undefined) {
1859
- oDate.setDate(oDate.getDate() + oDateValue.dayNumberOfWeek - 1);
1860
- }
1861
- }
1862
- }
2137
+ oDate = UniversalDate.getInstance(new Date(0), sCalendarType);
2138
+ oDate.setUTCEra(oDateValue.era || UniversalDate.getCurrentEra(sCalendarType));
2139
+ oDate.setUTCFullYear(iYear);
2140
+ oDate.setUTCMonth(oDateValue.month || 0);
2141
+ oDate.setUTCDate(oDateValue.day || 1);
2142
+ oDate.setUTCHours(oDateValue.hour || 0);
2143
+ oDate.setUTCMinutes(oDateValue.minute || 0);
2144
+ oDate.setUTCSeconds(oDateValue.second || 0);
2145
+ oDate.setUTCMilliseconds(oDateValue.millisecond || 0);
2146
+ if (bStrict && (oDateValue.day || 1) !== oDate.getUTCDate()) {
2147
+ // check if valid date given - if invalid, day is not the same (31.Apr -> 1.May)
2148
+ return null;
2149
+ }
2150
+ if (oDateValue.week !== undefined && (oDateValue.month === undefined || oDateValue.day === undefined)) {
2151
+ //check that the week is only set if the day/month has not been set, because day/month have higher precedence than week
2152
+ oDate.setUTCWeek({
2153
+ year: oDateValue.weekYear || oDateValue.year,
2154
+ week: oDateValue.week
2155
+ });
1863
2156
 
1864
- if (oDateValue.valid) {
1865
- oDate = oDate.getJSDate();
1866
- return oDate;
2157
+ //add the dayNumberOfWeek to the current day
2158
+ if (oDateValue.dayNumberOfWeek !== undefined) {
2159
+ oDate.setUTCDate(oDate.getUTCDate() + oDateValue.dayNumberOfWeek - 1);
1867
2160
  }
1868
2161
  }
1869
2162
 
1870
- return null;
2163
+ oDate = oDate.getJSDate();
2164
+
2165
+ // Set the tzDiff based on the timezone difference
2166
+ if (!bUTC && (
2167
+ (oDateValue.lastTimezonePatternSymbol === "V" && oDateValue.timezone)
2168
+ || oDateValue.tzDiff === undefined
2169
+ )) {
2170
+ // The last parsed timezone pattern will be considered. If this is the "V" pattern for the IANA timezone ID, it needs
2171
+ // to be calculated here. The tzDiff cannot be determined in the parse method because we need the parsed parts to calculate it.
2172
+ if (oDateValue.timezone) {
2173
+ sTimezone = oDateValue.timezone;
2174
+ }
2175
+
2176
+ if (sTimezone) {
2177
+ oDateValue.tzDiff = TimezoneUtil.calculateOffset(oDate, sTimezone);
2178
+ }
2179
+ }
2180
+ if (oDateValue.tzDiff) {
2181
+ // tzDiff is in seconds for a higher precision (historical timezone might have differences in seconds)
2182
+ // e.g. new Date(Date.UTC(1730, 0, 1))
2183
+ // is in Berlin: Sun Jan 01 1730 00:53:28 GMT+0053 (Central European Standard Time)
2184
+ oDate.setUTCSeconds((oDateValue.second || 0) + oDateValue.tzDiff);
2185
+ }
2186
+ return oDate;
1871
2187
  };
1872
2188
 
1873
2189
  // Copy the properties of object2 into object1 without
@@ -1906,21 +2222,47 @@ sap.ui.define([
1906
2222
  /**
1907
2223
  * Parse a string which is formatted according to the given format options.
1908
2224
  *
2225
+ * Uses the timezone from {@link sap.ui.core.Configuration#getTimezone}, which falls back to the
2226
+ * browser's local timezone to convert the given date.
2227
+ *
2228
+ * @example <caption>DateTime (with timezone "Europe/Berlin")</caption>
2229
+ * var oDate = new Date(Date.UTC(2021, 11, 24, 13, 37));
2230
+ * DateFormat.getDateTimeInstance().parse("Dec 24, 2021, 2:37:00 PM");
2231
+ * // output: oDate
2232
+ *
1909
2233
  * @param {string} sValue the string containing a formatted date/time value
1910
2234
  * @param {boolean} bUTC whether to use UTC, if no timezone is contained
1911
- * @param {boolean} bStrict to use strict value check
2235
+ * @param {boolean} bStrict whether to use strict value check
1912
2236
  * @return {Date|Date[]} the parsed value(s)
1913
2237
  * @public
1914
2238
  */
1915
2239
  DateFormat.prototype.parse = function(sValue, bUTC, bStrict) {
2240
+ var sTimezone;
2241
+ if (bUTC === undefined && this.type !== mDateFormatTypes.DATETIME_WITH_TIMEZONE) {
2242
+ bUTC = this.oFormatOptions.UTC;
2243
+ }
2244
+ // preserve UTC parameter for fallback instances (must inherit format option UTC from parent)
2245
+ var bUTCInputParameter = bUTC;
2246
+ if (this.type === mDateFormatTypes.DATETIME_WITH_TIMEZONE) {
2247
+
2248
+ // UTC and timezone are not supported at the same time, therefore set bUTC to false
2249
+ sTimezone = bUTC;
2250
+ bUTC = false;
2251
+
2252
+ // timezone is required to calculate the timezone offset therefore it must be a valid IANA timezone ID
2253
+ if (sTimezone != null && !TimezoneUtil.isValidTimezone(sTimezone)) {
2254
+ Log.error("The given timezone isn't valid.");
2255
+ return null;
2256
+ }
2257
+ }
2258
+
1916
2259
  sValue = sValue == null ? "" : String(sValue).trim();
1917
2260
 
1918
2261
  var oDateValue;
1919
2262
  var sCalendarType = this.oFormatOptions.calendarType;
1920
2263
 
1921
- if (bUTC === undefined) {
1922
- bUTC = this.oFormatOptions.UTC;
1923
- }
2264
+ // default the timezone to the local timezone to always enforce the conversion
2265
+ sTimezone = sTimezone || sap.ui.getCore().getConfiguration().getTimezone();
1924
2266
 
1925
2267
  if (bStrict === undefined) {
1926
2268
  bStrict = this.oFormatOptions.strictParsing;
@@ -1937,29 +2279,38 @@ sap.ui.define([
1937
2279
  return oJSDate;
1938
2280
  }
1939
2281
 
1940
- oDateValue = this._parse(sValue, this.aFormatArray, bUTC, bStrict);
2282
+ oDateValue = this._parse(sValue, this.aFormatArray, bUTC, bStrict, sTimezone);
1941
2283
 
1942
2284
  // If input value has not been completely parsed, mark it as invalid
1943
2285
  if (oDateValue.index === 0 || oDateValue.index < sValue.length) {
1944
2286
  oDateValue.valid = false;
1945
2287
  }
1946
2288
 
1947
- oJSDate = fnCreateDate(oDateValue, sCalendarType, bUTC, bStrict);
2289
+ oJSDate = fnCreateDate(oDateValue, sCalendarType, bUTC, bStrict, sTimezone);
1948
2290
 
1949
2291
  if (oJSDate) {
2292
+ if (this.type === mDateFormatTypes.DATETIME_WITH_TIMEZONE) {
2293
+ // fill fields according to showTimezone option and parsed values
2294
+ if (this.oFormatOptions.showTimezone === DateFormatTimezoneDisplay.Hide) {
2295
+ return [oJSDate, undefined];
2296
+ } else if (this.oFormatOptions.showTimezone === DateFormatTimezoneDisplay.Only) {
2297
+ return [undefined, oDateValue.timezone];
2298
+ }
2299
+ return [oJSDate, oDateValue.timezone || undefined];
2300
+ }
1950
2301
  return oJSDate;
1951
2302
  }
1952
2303
 
1953
2304
  } else {
1954
- var aDateValues = this._parseInterval(sValue, sCalendarType, bUTC, bStrict);
2305
+ var aDateValues = this._parseInterval(sValue, sCalendarType, bUTC, bStrict, sTimezone);
1955
2306
  var oJSDate1, oJSDate2;
1956
2307
 
1957
2308
  if (aDateValues && aDateValues.length == 2) {
1958
2309
  var oDateValue1 = mergeWithoutOverwrite(aDateValues[0], aDateValues[1]);
1959
2310
  var oDateValue2 = mergeWithoutOverwrite(aDateValues[1], aDateValues[0]);
1960
2311
 
1961
- oJSDate1 = fnCreateDate(oDateValue1, sCalendarType, bUTC, bStrict);
1962
- oJSDate2 = fnCreateDate(oDateValue2, sCalendarType, bUTC, bStrict);
2312
+ oJSDate1 = fnCreateDate(oDateValue1, sCalendarType, bUTC, bStrict, sTimezone);
2313
+ oJSDate2 = fnCreateDate(oDateValue2, sCalendarType, bUTC, bStrict, sTimezone);
1963
2314
 
1964
2315
  if (oJSDate1 && oJSDate2) {
1965
2316
 
@@ -1981,13 +2332,17 @@ sap.ui.define([
1981
2332
  }
1982
2333
  }
1983
2334
 
2335
+ // this instance is not the fallback instance therefore we call the fallback instances (which have this flag set to true)
1984
2336
  if (!this.bIsFallback) {
1985
2337
  var vDate;
1986
2338
 
1987
2339
  this.aFallbackFormats.every(function(oFallbackFormat) {
1988
- vDate = oFallbackFormat.parse(sValue, bUTC, bStrict);
2340
+ vDate = oFallbackFormat.parse(sValue, bUTCInputParameter, bStrict);
1989
2341
 
1990
2342
  if (Array.isArray(vDate)) {
2343
+ if (oFallbackFormat.type === mDateFormatTypes.DATETIME_WITH_TIMEZONE) {
2344
+ return false;
2345
+ }
1991
2346
  return !(vDate[0] && vDate[1]);
1992
2347
  } else {
1993
2348
  return !vDate;
@@ -2173,12 +2528,13 @@ sap.ui.define([
2173
2528
  *
2174
2529
  * @param {Date} oJSDate the value to format
2175
2530
  * @param {boolean} bUTC whether to use UTC
2531
+ * @param {number[]} aRange scale ranges
2532
+ * @param {string} sTimezone the IANA timezone ID
2176
2533
  * @return {string} the formatted output value or null if relative formatting not possible
2177
2534
  * @private
2178
2535
  */
2179
- DateFormat.prototype.formatRelative = function(oJSDate, bUTC, aRange) {
2180
-
2181
- var oToday = new Date(), oDateUTC,
2536
+ DateFormat.prototype.formatRelative = function(oJSDate, bUTC, aRange, sTimezone) {
2537
+ var oToday = convertToTimezone(new Date(), sTimezone), oDateUTC,
2182
2538
  sScale = this.oFormatOptions.relativeScale || "day",
2183
2539
  iDiff, sPattern, iDiffSeconds;
2184
2540
 
@@ -2194,17 +2550,13 @@ sap.ui.define([
2194
2550
 
2195
2551
  // For dates normalize to UTC to avoid issues with summer-/wintertime
2196
2552
  if (sScale == "year" || sScale == "month" || sScale == "day") {
2197
- oToday = new Date(Date.UTC(oToday.getFullYear(), oToday.getMonth(), oToday.getDate()));
2553
+ oToday = new Date(Date.UTC(oToday.getUTCFullYear(), oToday.getUTCMonth(), oToday.getUTCDate()));
2198
2554
 
2199
2555
  oDateUTC = new Date(0);
2200
2556
 
2201
- if (bUTC) {
2202
- // The Date.UTC function doesn't accept years before 1900 (converts years before 100 into 1900 + years).
2203
- // Using setUTCFullYear to workaround this issue.
2204
- oDateUTC.setUTCFullYear(oJSDate.getUTCFullYear(), oJSDate.getUTCMonth(), oJSDate.getUTCDate());
2205
- } else {
2206
- oDateUTC.setUTCFullYear(oJSDate.getFullYear(), oJSDate.getMonth(), oJSDate.getDate());
2207
- }
2557
+ // The Date.UTC function doesn't accept years before 1900 (converts years before 100 into 1900 + years).
2558
+ // Using setUTCFullYear to workaround this issue.
2559
+ oDateUTC.setUTCFullYear(oJSDate.getUTCFullYear(), oJSDate.getUTCMonth(), oJSDate.getUTCDate());
2208
2560
 
2209
2561
  oJSDate = oDateUTC;
2210
2562
  }
@@ -2265,7 +2617,7 @@ sap.ui.define([
2265
2617
  // Fixes the scale for months/weeks
2266
2618
  // when involved months do not have 30 days
2267
2619
  function fixScaleForMonths(oJSDate, oToday, sScale, iDiffSeconds) {
2268
- var iMonthDiff = Math.abs(oJSDate.getMonth() - oToday.getMonth());
2620
+ var iMonthDiff = Math.abs(oJSDate.getUTCMonth() - oToday.getUTCMonth());
2269
2621
  if (sScale === "week" && iMonthDiff === 2) {
2270
2622
  // 2 months diff
2271
2623
  // e.g. March 1st - Jan 31st
@@ -2273,23 +2625,23 @@ sap.ui.define([
2273
2625
  } else if (sScale === "week" && iMonthDiff === 1) {
2274
2626
  // same day but different month
2275
2627
  // e.g. March 1st - Feb 1st
2276
- if (oJSDate.getDate() === oToday.getDate()
2628
+ if (oJSDate.getUTCDate() === oToday.getUTCDate()
2277
2629
  // future date
2278
2630
  // e.g. Feb 14th - 15. Mar 15th (29/30 days diff) => 1 month
2279
- || (iDiffSeconds < 0 && oJSDate.getDate() < oToday.getDate())
2631
+ || (iDiffSeconds < 0 && oJSDate.getUTCDate() < oToday.getUTCDate())
2280
2632
  // past date
2281
2633
  // e.g. Mar 15th - Feb 14th (29/30 days diff) => 1 month
2282
- || (iDiffSeconds > 0 && oJSDate.getDate() > oToday.getDate())
2634
+ || (iDiffSeconds > 0 && oJSDate.getUTCDate() > oToday.getUTCDate())
2283
2635
  ) {
2284
2636
  return "month";
2285
2637
  }
2286
2638
  } else if (sScale === "month" && iMonthDiff === 1) {
2287
2639
  // future date
2288
2640
  // e.g. Mar 14th - Apr 13th (30 days diff)
2289
- if ((iDiffSeconds > 0 && oJSDate.getDate() < oToday.getDate())
2641
+ if ((iDiffSeconds > 0 && oJSDate.getUTCDate() < oToday.getUTCDate())
2290
2642
  // past date
2291
2643
  // Feb 14th - Jan 15th (30 days diff)
2292
- || (iDiffSeconds < 0 && oJSDate.getDate() > oToday.getDate())
2644
+ || (iDiffSeconds < 0 && oJSDate.getUTCDate() > oToday.getUTCDate())
2293
2645
  ) {
2294
2646
  return "week";
2295
2647
  }
@@ -2325,7 +2677,7 @@ sap.ui.define([
2325
2677
  var oDateCopy = new Date(oDate.getTime());
2326
2678
 
2327
2679
  for (var i = iStartIndex; i < aFields.length; i++) {
2328
- sMethodName = "set" + aFields[iStartIndex];
2680
+ sMethodName = "setUTC" + aFields[iStartIndex];
2329
2681
  oDateCopy[sMethodName].apply(oDateCopy, [0]);
2330
2682
  }
2331
2683
  return oDateCopy;
@@ -2333,14 +2685,14 @@ sap.ui.define([
2333
2685
 
2334
2686
  var mRelativeDiffs = {
2335
2687
  year: function(oFromDate, oToDate) {
2336
- return oToDate.getFullYear() - oFromDate.getFullYear();
2688
+ return oToDate.getUTCFullYear() - oFromDate.getUTCFullYear();
2337
2689
  },
2338
2690
  month: function(oFromDate, oToDate) {
2339
- return oToDate.getMonth() - oFromDate.getMonth() + (this.year(oFromDate, oToDate) * 12);
2691
+ return oToDate.getUTCMonth() - oFromDate.getUTCMonth() + (this.year(oFromDate, oToDate) * 12);
2340
2692
  },
2341
2693
  week: function(oFromDate, oToDate, oFormat) {
2342
- var iFromDay = oFormat._adaptDayOfWeek(oFromDate.getDay());
2343
- var iToDay = oFormat._adaptDayOfWeek(oToDate.getDay());
2694
+ var iFromDay = oFormat._adaptDayOfWeek(oFromDate.getUTCDay());
2695
+ var iToDay = oFormat._adaptDayOfWeek(oToDate.getUTCDay());
2344
2696
 
2345
2697
  oFromDate = cutDateFields(oFromDate, 3);
2346
2698
  oToDate = cutDateFields(oToDate, 3);