diff --git a/currency.api.php b/currency.api.php
index 547c28e..36b1bbf 100644
--- a/currency.api.php
+++ b/currency.api.php
@@ -34,3 +34,33 @@ function hook_currency_info_alter(array $currencies) {
   // Let's pretend the euro has 1000 subunits.
   $currencies['EUR']['minor_unit'] = 3;
 }
+
+
+/**
+ * Expose currency locale formats.
+ *
+ * @return array
+ *   An array of CurrencyLocaleFormat objects, keyed by their formats.
+ */
+function hook_currency_locale_format_info() {
+  $formats['¤###.###.##0,00'] = new CurrencyLocaleFormat(array(
+    'country_code' => 'nl',
+    'format' => '¤###.###.##0,00',
+    'language_code' => 'nl',
+  ));
+
+  return $currencies;
+}
+
+/**
+ * Alter exposed currency locale formats.
+ *
+ * @param array
+ *   An array of CurrencyLocaleFormat objects, keyed by their format.
+ *
+ * @return NULL
+ */
+function hook_currency_locale_format_info_alter(array $currency_locale_formats) {
+  // Make sure trillions are formatted correctly.
+  $currencies['¤###.###.##0,00']['format'] = '¤###.###.###.##0,00';
+}
diff --git a/currency.currency.inc b/currency.currency.inc
index eb1c80a..04f9ebe 100644
--- a/currency.currency.inc
+++ b/currency.currency.inc
@@ -829,3 +829,34 @@ function currency_currency_info() {
 
   return $currencies_keyed;
 }
+
+/**
+ * Implements hook_currency_locale_format_info().
+ */
+function currency_currency_locale_format_info() {
+  $formats = array(
+    new CurrencyLocaleFormat(array(
+    new CurrencyLocaleFormat(array(
+      'country_codes' => array('de', 'fr'),
+      'format' => 'XXX -###,###,###,##0.00',
+      'language_codes' => array('de', 'fr'),
+    )),
+      'country_code' => array('be', 'nl'),
+      'format' => '¤-###.###.###.##0,00',
+      'language_code' => array('nl'),
+    )),
+    new CurrencyLocaleFormat(array(
+      'country_code' => array('uk', 'us'),
+      'format' => '¤-###,###,###,##0.00',
+      'language_code' => array('en'),
+    )),
+  );
+
+  // Key currencies by their ISO 4217 codes, which act as their machine names.
+  $formats_keyed = array();
+  foreach ($formats as $format) {
+    $formats_keyed[$format->format] = $format;
+  }
+
+  return $formats_keyed;
+}
\ No newline at end of file
diff --git a/currency.info b/currency.info
index 9f6abf8..30fb11b 100755
--- a/currency.info
+++ b/currency.info
@@ -4,5 +4,8 @@ core = 7.x
 configure = admin/config/regional/currency
 dependencies[] = ctools
 files[] = includes/Currency.inc
+files[] = includes/CurrencyLocaleFormat.inc
 files[] = includes/CurrencyBaseAbstract.inc
+files[] = includes/CurrencyExportableInterface.inc
 files[] = tests/CurrencyCRUDWebTestCase.test
+files[] = tests/CurrencyLocaleFormatCRUDWebTestCase.test
diff --git a/currency.install b/currency.install
index 2d6757f..6494bbc 100644
--- a/currency.install
+++ b/currency.install
@@ -9,6 +9,7 @@
  * Implements hook_schema().
  */
 function currency_schema() {
+  ctools_include('export');
   $schema['currency'] = array(
     'description' => 'Currency information based on ISO 4127.',
     'export' => array(
@@ -59,6 +60,56 @@ function currency_schema() {
   foreach (get_class_vars('Currency') as $property => $default_value) {
     $schema['currency']['fields'][$property]['object default'] = $default_value;
   }
+  $schema['currency_locale_format'] = array(
+    'description' => 'Locale-specific amount formatting.',
+    'export' => array(
+      'key' => 'name',
+      'key name' => 'Name',
+      'default hook' => 'currency_locale_format',
+      'object' => 'CurrencyLocaleFormat',
+      'save callback' => 'currency_ctools_export_object_save',
+    ),
+    'fields' => array(
+      'country_code' => array(
+        'type' => 'varchar',
+        'length' => 2,
+      ),
+      'export_module' => array(
+        'type' => 'varchar',
+        'length' => 255,
+      ),
+      'export_type' => array(
+        'type' => 'int',
+        'length' => 'tiny',
+      ),
+      'format' => array(
+        'type' => 'varchar',
+        'length' => 255,
+      ),
+      'language_code' => array(
+        'type' => 'varchar',
+        'length' => 3,
+      ),
+      'name' => array(
+        'type' => 'varchar',
+        'length' => 255,
+      ),
+    ),
+    'primary key' => array('name'),
+    'unique keys' => array(
+      'format' => array('format'),
+    ),
+    'indexes' => array(
+      'country_code' => array('country_code'),
+      'language_code' => array('language_code'),
+    ),
+  );
+  // Set Ctools object defaults based on CurrencyLocaleFormat's default values.
+  foreach (get_class_vars('CurrencyLocaleFormat') as $property => $default_value) {
+    if (isset($schema['currency_locale_format']['fields'][$property])) {
+      $schema['currency_locale_format']['fields'][$property]['object default'] = $default_value;
+    }
+  }
 
   return $schema;
 }
diff --git a/currency.module b/currency.module
index 39c640c..fee6da5 100644
--- a/currency.module
+++ b/currency.module
@@ -25,6 +25,12 @@ function currency_hook_info() {
   $hooks['currency_info_alter'] = array(
     'group' => 'currency',
   );
+  $hooks['currency_locale_format_info'] = array(
+    'group' => 'currency',
+  );
+  $hooks['currency_locale_format_info_alter'] = array(
+    'group' => 'currency',
+  );
 
   return $hooks;
 }
@@ -38,3 +44,23 @@ function currency_views_api() {
     'path' => drupal_get_path('module', 'currency') . '/views',
   );
 }
+
+function currency_ctools_export_object_save(CurrencyExportableInterface $exportable) {
+  $exportable->validate();
+  $exportable->export_type = $exportable->export_type | EXPORT_IN_DATABASE;
+  $schema = drupal_get_schema($exportable->table);
+    $fields = array();
+  foreach ($schema['fields'] as $field => $info) {
+    if (property_exists($exportable, $field)) {
+      $fields[$field] = $exportable->$field;
+    }
+  }
+  $primary_key = $schema['primary key'][0];
+
+  return db_merge($exportable->table)
+    ->key(array(
+      $primary_key => $exportable->$primary_key,
+    ))
+    ->fields($fields)
+    ->execute();
+}
\ No newline at end of file
diff --git a/includes/CurrencyExportableInterface.inc b/includes/CurrencyExportableInterface.inc
new file mode 100644
index 0000000..a65746e
--- /dev/null
+++ b/includes/CurrencyExportableInterface.inc
@@ -0,0 +1,15 @@
+<?php
+
+/**
+ * Contains interface CurrencyExportableInterface.
+ */
+
+interface CurrencyExportableInterface {
+
+  /**
+   * Validates the exportable.
+   *
+   * @throws Exception
+   */
+  function validate();
+}
\ No newline at end of file
diff --git a/includes/CurrencyLocaleFormat.inc b/includes/CurrencyLocaleFormat.inc
new file mode 100644
index 0000000..83518b3
--- /dev/null
+++ b/includes/CurrencyLocaleFormat.inc
@@ -0,0 +1,71 @@
+<?php
+
+/**
+ * @file
+ * Contains class CurrencyLocaleFormat.
+ */
+
+/**
+ * Describes a currency format.
+ */
+class CurrencyLocaleFormat extends CurrencyBaseAbstract implements CurrencyExportableInterface {
+
+  /**
+   * ISO 3166 country code.
+   *
+   * @var string
+   */
+  public $country_code = '';
+
+  /**
+   * Implements Chaos tools' exportable object "export_module" property.
+   */
+  public $export_module = '';
+
+  /**
+   * Implements Chaos tools' exportable object "export_type" property.
+   */
+  public $export_type = '';
+
+  /**
+   * The minor unit, or exponent (as in 10^$minor_unit) that results in the
+   * number of minor units.
+   *
+   * @var string
+   *   See Currency::format()'s $format argument for more information.
+   */
+  public $format = '';
+
+  /**
+   * ISO 639-1 language code.
+   *
+   * @var string
+   */
+  public $language_code = 'zxx';
+
+  /**
+   * The currency format unique machine name.
+   *
+   * @var string
+   */
+  public $name = '';
+
+  /**
+   * Implements Chaos tools' exportable object "table" property.
+   */
+  public $table = 'currency_locale_format';
+
+  /**
+   * Implements CurrencyExportableInterface::validate().
+   */
+  function validate() {
+    $properties = array('country_code', 'format', 'language_code', 'name');
+    foreach ($properties as $property) {
+      if (empty($this->$property)) {
+        throw new Exception(t('Missing value for %property.', array(
+          '%property' => $property,
+        )));
+      }
+    }
+  }
+}
diff --git a/tests/CurrencyLocaleFormatCRUDWebTestCase.test b/tests/CurrencyLocaleFormatCRUDWebTestCase.test
new file mode 100644
index 0000000..cbd744b
--- /dev/null
+++ b/tests/CurrencyLocaleFormatCRUDWebTestCase.test
@@ -0,0 +1,82 @@
+<?php
+
+/**
+ * @file
+ * Contains class CurrencyLocaleFormatCRUDWebTestCase.
+ */
+
+/**
+ * Tests CRUD.
+ */
+class CurrencyLocaleFormatCRUDWebTestCase extends DrupalWebTestCase {
+
+  static function getInfo() {
+    return array(
+      'name' => 'Currency format CRUD',
+      'group' => 'Currency',
+    );
+  }
+
+  function setUp(array $modules = array()) {
+    parent::setUp($modules + array('currency'));
+  }
+
+  /**
+   * Test CRUD functionality.
+   */
+  function testCRUD() {
+    // Test creating a new currency format.
+    $defaults_valid = TRUE;
+    $currency_locale_format = ctools_export_crud_new('currency_locale_format');
+    foreach (get_class_vars('CurrencyLocaleFormat') as $property => $default_value) {
+      if ($currency_locale_format->$property != $default_value) {
+        $defaults_valid = FALSE;
+        break;
+      }
+    }
+    $this->assertTrue($defaults_valid, 'Chaos tools correctly creates a new currency format.');
+
+    // Test inserting a currency format.
+    $currency_locale_format = new CurrencyLocaleFormat(array(
+      'country_code' => 'de',
+      'format' => 'foo',
+      'language_code' => 'de',
+      'name'=> 'foo',
+    ));
+    ctools_export_crud_save('currency_locale_format', $currency_locale_format);
+    $count = db_query("SELECT COUNT(1) FROM {currency_locale_format} WHERE country_code = :country_code AND format = :format AND language_code = :language_code AND name = :name", array(
+      ':country_code' => $currency_locale_format->country_code,
+      ':format' => $currency_locale_format->format,
+      ':language_code' => $currency_locale_format->language_code,
+      ':name'=> $currency_locale_format->name,
+    ))->fetchField();
+    $this->assertTrue($count, 'Chaos tools correctly inserts a currency format.');
+
+    // We need the saved format for the rest of the test.
+    if ($count) {
+      // Test loading a currency format.
+      $currency_locale_format_loaded = ctools_export_crud_load('currency_locale_format', $currency_locale_format->name);
+      $this->assertFalse(array_diff_assoc(get_object_vars($currency_locale_format), get_object_vars($currency_locale_format_loaded)), 'Chaos tools correctly loads a currency format.');
+
+      // Test updating a currency format.
+      $currency_locale_format->country_code = 'gb';
+      $currency_locale_format->format = 'bar';
+      $currency_locale_format->language_code = 'en';
+      ctools_export_crud_save('currency_locale_format', $currency_locale_format);
+      $count = db_query("SELECT COUNT(1) FROM {currency_locale_format} WHERE country_code = :country_code AND format = :format AND language_code = :language_code AND name = :name", array(
+        ':country_code' => $currency_locale_format->country_code,
+        ':format' => $currency_locale_format->format,
+        ':language_code' => $currency_locale_format->language_code,
+        ':name'=> $currency_locale_format->name,
+      ))->fetchField();
+      $this->assertTrue($count, 'Chaos tools correctly updates a currency format.');
+
+      // Test deleting a currency format.
+      ctools_export_crud_delete('currency_locale_format', $currency_locale_format->name);
+      $count = db_query("SELECT COUNT(1) FROM {currency_locale_format} WHERE format = :format", array(
+        ':format' => $currency_locale_format->format,
+      ))->fetchField();
+      $this->assertFalse($count, 'Chaos tools correctly deletes a currency format.');
+    }
+  }
+}
\ No newline at end of file
