<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="387030" data-post-id="387030">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="woylie" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/woylie/120/38856_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  woylie
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Thank you so much for the speedy fix!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="387030" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/localize-next-generation-localisation-ex-cldr-v3-0/73933/22">Post #21</a>
	                </div>
	            </div>
              <div id="likers-container-387030" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="387030"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #21"></div>
  </section>
</div>
    <div class="postbit" id="387072" data-post-id="387072">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="kip" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kip/120/1440_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  kip
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>ex_cldr Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Todays launch is <a href="https://hex.pm/packages/localize_person_names" rel="nofollow">localize_person_names</a> that implements person name formatting based upon the <a href="https://www.unicode.org/reports/tr35/tr35-personNames.html" rel="nofollow">CLDR Person Name specification</a>.</p>
<p>Person names are simultaneously one of the most important topics for good user engagement and one of the most under-satisfied capabilities in modern software.</p>
<p>In 2010, Patrick McKenzie published <a href="https://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/" rel="nofollow">Falsehoods Programmers Believe About Names</a>, a list of 40 assumptions about personal names that programmers routinely make and that are routinely wrong. Fifteen years later, the article is still being translated, cited, and re-linked — because its examples remain live bugs in production systems everywhere.  <code>localize_person_names</code> can be used to avoid nearly all of these pitfalls.</p>
<p>Naming mistakes can even lead to offensive or abuse material and in rare situations even legal issues.</p>
<p>The blog article <a href="https://zenn.dev/blue_jam/articles/5553aec104e710" rel="nofollow">多文化環境におけるパーソナルネームの扱い方</a> (Handling personal names in multicultural environments) documents a specific Japanese failure mode: using both family-name and given-name initials together.</p>
<ul>
<li>
<p><strong>不破 貞仁</strong> (Fuwa Sadahito) — family initial <code>不</code> + given initial <code>貞</code> = <code>不貞</code> (infidelity).</p>
</li>
<li>
<p><strong>大谷 麻美</strong> (Ōtani Asami) — family initial <code>大</code> + given initial <code>麻</code> = <code>大麻</code> (marijuana / cannabis).</p>
</li>
</ul>
<p>I’ve put together some guides to help understand the <a href="https://hexdocs.pm/localize_person_names/cultural_naming_conventions.html" rel="nofollow">cultural implications of naming</a>, <a href="https://hexdocs.pm/localize_person_names/integrating_existing_structs.html" rel="nofollow">how to integrate with existing applications</a> and <a href="https://hexdocs.pm/localize_person_names/message_formatting.html" rel="nofollow">how to integrate with Localize.Message</a>.</p>
<p>Let me know what you think!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="387072" data-batch-url="/posts/batch_likers">
                        9
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/localize-next-generation-localisation-ex-cldr-v3-0/73933/23">Post #22</a>
	                </div>
	            </div>
              <div id="likers-container-387072" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="387072"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #22"></div>
  </section>
</div>
    <div class="postbit" id="387142" data-post-id="387142">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="kip" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kip/120/1440_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  kip
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>ex_cldr Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Lauch Day <span class="hashtag-raw">#4</span> introduces <a href="https://hex.pm/packages/localize_address" rel="nofollow">localize_address</a> and <a href="https://hex.pm/packages/localize_phone_number" rel="nofollow">localize_phone_number</a>.</p>
<p>These are both NIF-based libraries using <a href="https://github.com/openvenues/libpostal" rel="nofollow">libpostal</a> and <a href="https://github.com/google/libphonenumber" rel="nofollow">libphonenumber</a> respectively. Consider them experimental until a 1.0 release.</p>
<p>This post covers address formatting. The next post about phone numbers.</p>
<h2><a name="p-387142-address-parsing-and-formatting-1" class="anchor" href="#p-387142-address-parsing-and-formatting-1" aria-label="Heading link" rel="nofollow"></a>Address Parsing and Formatting</h2>
<p>Addresses are a nightmare. Hard to parse, difficult to format. Different around the world. <code>libpostal</code> does the heavy lifting of parsing. It’s fabulous - but not perfect.  Then we use <a href="https://github.com/opencagedata/address-formatting" rel="nofollow">OpenCageData</a> for global formatting templates.</p>
<h3><a name="p-387142-examples-2" class="anchor" href="#p-387142-examples-2" aria-label="Heading link" rel="nofollow"></a>Examples</h3>
<p>There is a <a href="https://hexdocs.pm/localize_address/parsing_and_formatting.html" rel="nofollow">user guide</a> and a few <a href="https://hexdocs.pm/localize_address/famous_addresses.html" rel="nofollow">famous examples</a>.  Here are some:</p>
<h4><a name="p-387142-h-221b-baker-street-3" class="anchor" href="#p-387142-h-221b-baker-street-3" aria-label="Heading link" rel="nofollow"></a>221B Baker Street</h4>
<p>The fictional London residence of Sherlock Holmes, as described by Arthur Conan Doyle. Today a real museum occupies the address.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex&gt; {:ok, address} = Localize.Address.parse(
...&gt;   "221b BAKER street, LONDON nw1 6xe, united kingdom",
...&gt;   territory: "GB", capitalize: true
...&gt; )
iex&gt; address.house_number
"221b"
iex&gt; address.road
"Baker Street"
iex&gt; address.postcode
"NW1 6XE"

iex&gt; {:ok, formatted} = Localize.Address.to_string(address)
iex&gt; IO.puts(formatted)
221b Baker Street
London
NW1 6XE
United Kingdom
</code></pre>
<h3><a name="p-387142-the-imperial-palace-tokyo-4" class="anchor" href="#p-387142-the-imperial-palace-tokyo-4" aria-label="Heading link" rel="nofollow"></a>The Imperial Palace, Tokyo</h3>
<p>The primary residence of the Emperor of Japan, in the Chiyoda ward of Tokyo.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex&gt; {:ok, address} = Localize.Address.parse(
...&gt;   "1-1 CHIYODA, chiyoda-ku, tokyo 100-8111, JAPAN",
...&gt;   territory: "JP", capitalize: true
...&gt; )
iex&gt; address.city
"Tokyo"
iex&gt; address.postcode
"100-8111"

iex&gt; {:ok, formatted} = Localize.Address.to_string(address)
iex&gt; IO.puts(formatted)
1-1
Chiyoda Chiyoda-Ku
Tokyo, 100-8111
Japan
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="387142" data-batch-url="/posts/batch_likers">
                        8
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/localize-next-generation-localisation-ex-cldr-v3-0/73933/24">Post #23</a>
	                </div>
	            </div>
              <div id="likers-container-387142" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="387142"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #23"></div>
  </section>
</div>
    <div class="postbit" id="387143" data-post-id="387143">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="kip" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kip/120/1440_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  kip
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>ex_cldr Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Localize Launch Day <span class="hashtag-raw">#4</span> - <a href="https://hex.pm/packages/localize_phone_number" rel="nofollow">localize_phone_number</a>.</p>
<h2><a name="p-387143-phone-number-parsing-and-formatting-1" class="anchor" href="#p-387143-phone-number-parsing-and-formatting-1" aria-label="Heading link" rel="nofollow"></a>Phone number parsing and formatting</h2>
<p>Phone numbers are at least structured data and <code>libphonenumber</code> does both the parsing and formatting.  There is a <a href="https://hexdocs.pm/localize_phone_number/parsing_and_formatting.html" rel="nofollow">user guide</a>.</p>
<h3><a name="p-387143-capitalization-2" class="anchor" href="#p-387143-capitalization-2" aria-label="Heading link" rel="nofollow"></a>Capitalization</h3>
<p>There is a <code>:capitalize</code> option to parsing (and a <code>capitalise/1</code> function) that will titlecase and capitalise addressing as appropriate. It’s a heuristic on my behalf but I think it produces reasonable results. This can be quite tricky depending on the language. So we use <a href="https://hex.pm/packages/unicode_string" rel="nofollow">unicode_string</a> to handle it since it knows about localized casing.  Here are some tricky bits that <code>unicode_string</code> helps us handle:</p>
<ul>
<li>
<p>Dutch, “IJ” is treated as a single unit at the start of a word — when titlecasing “ijsselmeer”, the correct result is “IJsselmeer” (both I and J capitalized), not “Ijsselmeer”. This requires understanding extended grapheme clusters because the titlecase operation needs to uppercase two codepoints at the word boundary, not just one.</p>
</li>
<li>
<p>Turkish/Azeri (<code>:tr</code>, <code>:az</code>) — dotted vs dotless I (<code>i</code> ↔ <code>İ</code> and <code>ı</code> ↔ <code>I</code>)</p>
</li>
<li>
<p>Lithuanian (<code>:lt</code>) — accent handling with soft-dotted characters</p>
</li>
<li>
<p>Greek (<code>:el</code>) — diacritics removed on uppercase, final sigma handling</p>
</li>
</ul>
<h3><a name="p-387143-examples-3" class="anchor" href="#p-387143-examples-3" aria-label="Heading link" rel="nofollow"></a>Examples</h3>
<p>There is also a set of <a href="https://hexdocs.pm/localize_phone_number/famous_phone_numbers.html" rel="nofollow">examples from film and literature</a>.</p>
<h4><a name="p-387143-ghostbusters-who-you-gonna-call-4" class="anchor" href="#p-387143-ghostbusters-who-you-gonna-call-4" aria-label="Heading link" rel="nofollow"></a>Ghostbusters — “Who you gonna call?”</h4>
<p>The Ghostbusters ad told New York to dial 555-2368. With a full area code the number parses and formats correctly:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex&gt; {:ok, phone_number} = Localize.PhoneNumber.parse("+1 212-555-2368")
iex&gt; Localize.PhoneNumber.to_string(phone_number, :e164)
{:ok, "+12125552368"}

iex&gt; Localize.PhoneNumber.to_string(phone_number, :national)
{:ok, "(212) 555-2368"}

iex&gt; Localize.PhoneNumber.territory(phone_number)
"US"

iex&gt; Localize.PhoneNumber.valid?(phone_number)
true
</code></pre>
<p>Without an area code the seven-digit local number still parses, but libphonenumber cannot validate it:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex&gt; {:ok, phone_number} = Localize.PhoneNumber.parse("555-2368", territory: "US")
iex&gt; Localize.PhoneNumber.valid?(phone_number)
false
</code></pre>
<h4><a name="p-387143-jenny-867-5309-5" class="anchor" href="#p-387143-jenny-867-5309-5" aria-label="Heading link" rel="nofollow"></a>Jenny — 867-5309</h4>
<p>Tommy Tutone’s 1981 hit gave us the most dialled number in pop music. As a seven-digit local number it parses but is not valid without an area code:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex&gt; {:ok, phone_number} = Localize.PhoneNumber.parse("867-5309", territory: "US")
iex&gt; Localize.PhoneNumber.to_string(phone_number, :national)
{:ok, "867-5309"}

iex&gt; Localize.PhoneNumber.valid?(phone_number)
false
</code></pre>
<p>Give Jenny a proper area code and the number becomes fully valid:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex&gt; {:ok, phone_number} = Localize.PhoneNumber.parse("+1 415-867-5309")
iex&gt; Localize.PhoneNumber.to_string(phone_number, :international)
{:ok, "+1 415-867-5309"}

iex&gt; Localize.PhoneNumber.valid?(phone_number)
true

iex&gt; Localize.PhoneNumber.type(phone_number)
:fixed_line_or_mobile
</code></pre>
<h4><a name="p-387143-the-shining-overlook-hotel-colorado-6" class="anchor" href="#p-387143-the-shining-overlook-hotel-colorado-6" aria-label="Heading link" rel="nofollow"></a>The Shining — Overlook Hotel, Colorado</h4>
<p>Stanley Kubrick’s Overlook Hotel sits in Colorado (area code 303). Using the 555 range reserved for fiction:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex&gt; {:ok, phone_number} = Localize.PhoneNumber.parse("(303) 555-0147", territory: "US")
iex&gt; Localize.PhoneNumber.to_string(phone_number, :e164)
{:ok, "+13035550147"}

iex&gt; Localize.PhoneNumber.to_string(phone_number, :international)
{:ok, "+1 303-555-0147"}

iex&gt; Localize.PhoneNumber.territory(phone_number)
"US"
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="387143" data-batch-url="/posts/batch_likers">
                        10
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/localize-next-generation-localisation-ex-cldr-v3-0/73933/25">Post #24</a>
	                </div>
	            </div>
              <div id="likers-container-387143" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="387143"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #24"></div>
  </section>
</div>
    <div class="postbit" id="387192" data-post-id="387192">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="kip" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kip/120/1440_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  kip
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>ex_cldr Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Day <span class="hashtag-raw">#5</span> of Localize launch week. I said today would be launch day for <a href="https://hex.pm/packages/intl" rel="nofollow">Intl</a> and indeed it is. But I’m also launching one additional library and a shiny new web site. In total today there are three things launching, all of which are clients of Localize.</p>
<ul>
<li><a href="https://hex.pm/packages/intl" rel="nofollow">Intl</a> which provides a Javascript Intl-like interface to Localize</li>
<li><a href="https://hex.pm/packages/calendrical" rel="nofollow">calendrical</a> which is a set of 17 calendar types plus more</li>
<li>And a Localize Playground web site at <a href="https://playground.elixir-localize.com" rel="nofollow">https://playground.elixir-localize.com</a></li>
</ul>
<h2><a name="p-387192-intl-1" class="anchor" href="#p-387192-intl-1" aria-label="Heading link" rel="nofollow"></a>Intl</h2>
<p>Since it’s just a wrapper it’s not a complex library. But I wanted to find a way to make localisation more approachable to more developers. Since <code>Intl</code> is <em>the</em> way to localise in javascript it seemed to make sense to have compatible API in Elixir. Thats <code>Intl</code>.  There’s a <a href="https://hexdocs.pm/intl/compatibility.html" rel="nofollow">compatibiilty guide</a> that helps understand the similarities and differences. And a <a href="https://hexdocs.pm/intl/getting_started.html" rel="nofollow">getting started guide</a> too.</p>
<h3><a name="p-387192-highlights-2" class="anchor" href="#p-387192-highlights-2" aria-label="Heading link" rel="nofollow"></a>Highlights</h3>
<ul>
<li>
<p><code>Intl.NumberFormat</code> — locale-aware number, currency, percent, and unit formatting.</p>
</li>
<li>
<p><code>Intl.DateTimeFormat</code> — locale-aware date and time formatting with range support.</p>
</li>
<li>
<p><code>Intl.ListFormat</code> — list joining with conjunctions, disjunctions, or unit separators.</p>
</li>
<li>
<p><code>Intl.DisplayNames</code> — localized names for regions, languages, currencies, scripts, calendars, and date-time fields.</p>
</li>
<li>
<p><code>Intl.RelativeTimeFormat</code> — relative time strings (“3 days ago”, “in 2 hours”).</p>
</li>
<li>
<p><code>Intl.PluralRules</code> — CLDR plural category selection (cardinal and ordinal).</p>
</li>
<li>
<p><code>Intl.Collator</code> — locale-aware string comparison and sorting via the Unicode Collation Algorithm.</p>
</li>
<li>
<p><code>Intl.DurationFormat</code> — locale-aware duration formatting.</p>
</li>
<li>
<p><code>Intl.Segmenter</code> — text segmentation into graphemes (built-in), words, and sentences (via optional <code>unicode_string</code> dependency).</p>
</li>
</ul>
<p>I hope developers who are more used to working on the front end might find is reasonably easy to continue their Elixir journey to localisation with <code>Intl</code>.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="387192" data-batch-url="/posts/batch_likers">
                        9
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/localize-next-generation-localisation-ex-cldr-v3-0/73933/26">Post #25</a>
	                </div>
	            </div>
              <div id="likers-container-387192" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="387192"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #25"></div>
  </section>
</div>
    <div class="postbit" id="387193" data-post-id="387193">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="kip" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kip/120/1440_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  kip
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>ex_cldr Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Next up in <a href="https://hex.pm/packages/calendrical" rel="nofollow">calendrical</a>.  I’ve always been fascinated by calendars and time keeping.While <a href="https://hex.pm/packages/ex_cldr_calendars" rel="nofollow">ex_cldr_calendars</a> has done a solid job for many years, it was never complete in my eyes. <code>Calendrical</code> is definitely next generation.</p>
<h2><a name="p-387193-lunar-calendars-1" class="anchor" href="#p-387193-lunar-calendars-1" aria-label="Heading link" rel="nofollow"></a>Lunar calendars</h2>
<p>While we had solar and lunisolar calendars for a some time now (which enables Persian, Chinese/Japanese/Korean calendars), we didn’t have support for lunar calendars (used to support Islamic and Hebrew calendars). That required a lot of work in <a href="https://hex.pm/packages/astro" rel="nofollow">Astro</a> to support moonrise and moonset. And also to do simulated lunar crescent detection. As a result, the moonrise/set functional accuracy is as good as it gets and the Islamic and Hebrew calendars are as accurate as they can practically be.</p>
<h2><a name="p-387193-composable-calendars-2" class="anchor" href="#p-387193-composable-calendars-2" aria-label="Heading link" rel="nofollow"></a>Composable calendars</h2>
<p>This is special-purpose calendar in which you actually compose a set of calendars. It’s particularly useful if you’re doing historical research and you need to track when the switch from Julian to Gregorian calendars occurred. It’s very niche. But it’s also very cool.</p>
<h2><a name="p-387193-user-defined-calendars-3" class="anchor" href="#p-387193-user-defined-calendars-3" aria-label="Heading link" rel="nofollow"></a>User-defined calendars</h2>
<p>This is made very easy by having a simple <code>use Calendrical</code> macro in a module and defining a few parameters. Lets you build almost any variant of a month-based or week-based calendar, Including calendars with leap years. And not only Gregorian calendars - you can override functions to have the behaviour you want. In fact most calendars in the library are defined this way now.</p>
<h2><a name="p-387193-calendrical-features-4" class="anchor" href="#p-387193-calendrical-features-4" aria-label="Heading link" rel="nofollow"></a>Calendrical Features</h2>
<ul>
<li>
<p><strong>17 CLDR-aligned calendar implementations</strong> — Gregorian, Persian, Coptic, Ethiopic (two eras), Japanese, Chinese, Korean (Dangi), Lunar Japanese, four Islamic variants (Civil, TBLA, Umm al-Qura, observational), Hebrew, Buddhist, Republic of China (Minguo), Indian National (Saka), and Julian.</p>
</li>
<li>
<p><strong><code>Calendrical.Behaviour</code></strong> — a <code>defmacro __using__</code> template that supplies default implementations of every <code>Calendar</code> and <code>Calendrical</code> callback. Users can define a new calendar in 60–200 lines by overriding only the parts that differ from the defaults.</p>
</li>
<li>
<p><strong>Composite calendars</strong> — <code>Calendrical.Composite</code> lets you build a calendar that uses one base calendar before a specified date and another after, supporting historical Julian-to-Gregorian transitions and similar splices.</p>
</li>
<li>
<p><strong>Localized formatting</strong> — era names, quarter names, month names, day names, day periods (AM/PM), and full date formatting via <code>Calendrical.localize/3</code> and <code>Calendrical.strftime_options!/1</code>. Falls through to all 766+ CLDR locales available from <code>Localize</code>.</p>
</li>
<li>
<p><strong>Fiscal-year calendars</strong> — pre-built fiscal calendars for ~50 territories (US, UK, AU, JP, …) plus a configurable <code>Calendrical.FiscalYear.calendar_for/1</code> factory.</p>
</li>
<li>
<p><strong>Date arithmetic</strong> — the standard <code>Date.shift/2</code> and <code>NaiveDateTime.shift/2</code> work across every Calendrical calendar.</p>
</li>
<li>
<p><strong>Date intervals</strong> — <code>Calendrical.Interval</code> returns <code>Date.Range</code> values for years, quarters, months, weeks, and days in any supported calendar, with <code>relation/2</code> implementing Allen’s interval algebra.</p>
</li>
<li>
<p><strong>k-day calculations</strong> — <code>Calendrical.Kday</code> finds the <em>n</em>-th occurrence of a given weekday relative to a date (e.g. “the second Tuesday in November”).</p>
</li>
<li>
<p><strong>Calendar formatters</strong> — <code>Calendrical.Format</code> and <code>Calendrical.Formatter</code> provide a behaviour-based plugin system for rendering calendars as HTML, Markdown, or any custom format.</p>
</li>
<li>
<p><strong>Astronomical calendar support</strong> — observational lunar calendars (Persian, Chinese, Korean, Lunar Japanese, observational Islamic, Saudi Rgsa, astronomical Umm al-Qura) use the <a href="https://hex.pm/packages/astro" rel="nofollow">Astro</a> library for equinox, lunar phase, and crescent visibility calculations.</p>
</li>
<li>
<p><strong>Ecclesiastical calendars</strong> — <code>Calendrical.Ecclesiastical</code> provides Reingold-style algorithms for the movable and fixed Christian feasts of three different traditions: <strong>Western</strong> (<code>easter_sunday/1</code>, <code>good_friday/1</code>, <code>pentecost/1</code>, <code>advent/1</code>, <code>christmas/1</code>, <code>epiphany/1</code>), <strong>Eastern Orthodox</strong> (<code>orthodox_easter_sunday/1</code>, <code>orthodox_good_friday/1</code>, <code>orthodox_pentecost/1</code>, <code>orthodox_advent/1</code>, <code>eastern_orthodox_christmas/1</code>), and <strong>astronomical</strong> (<code>astronomical_easter_sunday/1</code>, <code>astronomical_good_friday/1</code>, <code>paschal_full_moon/1</code> — the WCC 1997 proposed reckoning).</p>
</li>
<li>
<p><strong>Sigils</strong> — every Calendrical calendar works with Elixir’s native <code>~D</code>/<code>~U</code>/<code>~N</code> sigils via the standard calendar suffix: <code>~D[2024-09-01 Calendrical.Hebrew]</code>, <code>~D[1446-09-01 Calendrical.Islamic.UmmAlQura]</code>.</p>
</li>
</ul> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="387193" data-batch-url="/posts/batch_likers">
                        11
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/localize-next-generation-localisation-ex-cldr-v3-0/73933/27">Post #26</a>
	                </div>
	            </div>
              <div id="likers-container-387193" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="387193"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #26"></div>
  </section>
</div>
    <div class="postbit" id="387194" data-post-id="387194">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="kip" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kip/120/1440_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  kip
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>ex_cldr Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Last one for today and for this week. Elixir Playground - a way to get more familiar with locales and an explorer of some of the capabilities of CLDR as expose through Localize.</p>
<p>Visit it at <a href="https://playground.elixir-localize.com" rel="nofollow">https://playground.elixir-localize.com</a></p>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/3/3/33ee4561ef81ee02b4e1354393febbfb67faa8e4.jpeg" data-download-href="https://forum.elixirforum.com/uploads/default/33ee4561ef81ee02b4e1354393febbfb67faa8e4" title="image" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/optimized/3X/3/3/33ee4561ef81ee02b4e1354393febbfb67faa8e4_2_517x282.jpeg" alt="image" data-base62-sha1="7poQlwW8VFp9bnprql7wky5kj8U" width="517" height="282" srcset="https://forum.elixirforum.com/uploads/default/optimized/3X/3/3/33ee4561ef81ee02b4e1354393febbfb67faa8e4_2_517x282.jpeg, https://forum.elixirforum.com/uploads/default/optimized/3X/3/3/33ee4561ef81ee02b4e1354393febbfb67faa8e4_2_775x423.jpeg 1.5x, https://forum.elixirforum.com/uploads/default/optimized/3X/3/3/33ee4561ef81ee02b4e1354393febbfb67faa8e4_2_1034x564.jpeg 2x" data-dominant-color="111419"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">1200×657 30.2 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><p></p>
<p>It’s only running on a fly shared VPS so don’t expect super fast performance. You’ll notice I the top right-hand-side of the page there is a language selector. There are 25 or so languages localized for Localize Playground. All the messages are rendered through Gettext using Localize.Message MF2 message formats.</p>
<p>There’s even syntax highlighting now on MF2 messages you can see on the <a href="https://playground.elixir-localize.com/messages" rel="nofollow">Messages</a>. Syntax highlighting functions are now in <code>Localize</code> as of version 0.15.0.</p>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/6/d/6d95c9943bb5c63f67b129e74742765001d4eb06.jpeg" data-download-href="https://forum.elixirforum.com/uploads/default/6d95c9943bb5c63f67b129e74742765001d4eb06" title="image" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/optimized/3X/6/d/6d95c9943bb5c63f67b129e74742765001d4eb06_2_517x282.jpeg" alt="image" data-base62-sha1="fDqXFf5wIGicpI43IRwzyjpMc0C" width="517" height="282" srcset="https://forum.elixirforum.com/uploads/default/optimized/3X/6/d/6d95c9943bb5c63f67b129e74742765001d4eb06_2_517x282.jpeg, https://forum.elixirforum.com/uploads/default/optimized/3X/6/d/6d95c9943bb5c63f67b129e74742765001d4eb06_2_775x423.jpeg 1.5x, https://forum.elixirforum.com/uploads/default/optimized/3X/6/d/6d95c9943bb5c63f67b129e74742765001d4eb06_2_1034x564.jpeg 2x" data-dominant-color="101318"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">1200×657 30.7 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><p></p>
<p>It’s a long time since I’ve build an actual app and deployed it. My friend Claude helped a lot with it. I’m sure it’s got rough edges and several issues. Please do <a href="https://github.com/elixir-localize/localize_playground/issues" rel="nofollow">report issues</a> so I can improve it.</p>
<p>Of course it’s open source so you can <a href="https://github.com/elixir-localize/localize_playground" rel="nofollow">clone</a> it and run it locally.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="387194" data-batch-url="/posts/batch_likers">
                        8
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/localize-next-generation-localisation-ex-cldr-v3-0/73933/28">Post #27</a>
	                </div>
	            </div>
              <div id="likers-container-387194" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="387194"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #27"></div>
  </section>
</div>
    <div class="postbit" id="387195" data-post-id="387195">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="kip" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kip/120/1440_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  kip
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>ex_cldr Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Just wanted to note that I have completed an update to <a href="https://hex,pm/packages/ex_money" rel="nofollow">ex_money</a> to be supported on Localize and and update to <a href="https://hex.pm/packages/digital_token" rel="nofollow">digital_token</a> to revise how and what token data is downloaded from the ISO authority,  They will be out early next week.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="387195" data-batch-url="/posts/batch_likers">
                        13
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/localize-next-generation-localisation-ex-cldr-v3-0/73933/29">Post #28</a>
	                </div>
	            </div>
              <div id="likers-container-387195" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="387195"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #28"></div>
  </section>
</div>
    <div class="postbit" id="387301" data-post-id="387301">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="munksgaard" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/munksgaard/120/36998_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  munksgaard
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>As always, thank you for your work! I’m looking forward to porting our app to Localize <img src="https://forum.elixirforum.com/images/emoji/apple/heart.png?v=15" title=":heart:" class="emoji" alt=":heart:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="387301" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/localize-next-generation-localisation-ex-cldr-v3-0/73933/30">Post #29</a>
	                </div>
	            </div>
              <div id="likers-container-387301" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="387301"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #29"></div>
  </section>
</div>
    <div class="postbit" id="387302" data-post-id="387302">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="munksgaard" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/munksgaard/120/36998_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  munksgaard
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Question: I see the documentation for <a href="https://hexdocs.pm/localize/Localize.Message.html#format_to_safe_list/3" rel="noopener nofollow ugc">format_to_safe_list/3</a> says “This is the foundation for HTML/HEEX renderers in companion packages”. Are there any such packages yet, plans for some, or are you leaving that to the community?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="387302" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/localize-next-generation-localisation-ex-cldr-v3-0/73933/31">Post #30</a>
	                </div>
	            </div>
              <div id="likers-container-387302" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="387302"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #30"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/73933/load_more?page=4">Load more posts (15 remaining)</a>
</div></template></turbo-stream>