By far the best (easiest) way is to use the locale filter (inside [`get_locale()`][1]). 

First set up a quick function for retrieving a different language to use on the `locale` filter.

	/**
	 * A function returns with returns the user's selectd locale, if stored. 
	 */
	function wpse35622_get_new_locale($locale=false){
	$new_locale = get_user_meta(get_current_user_id(), 'wpse_locale', true);
		if($new_locale)
			return $new_locale;
	
		return $locale;
	}

I've left this as a global function, might be handy...? The rest of the plug-in I've wrapped inside a class.

It creates a drop-down of possible languages from which you can select.

## Drawbacks

 - Searches `wp-content/languages` for files of the form `xx_xx.mo`. If it's not of that form (not all .mo files are) the plug-in won't pick up on it!
 - The drop down gives a list of the found locales to choose from, but these are displayed in the 'xx_xx` format of locales, not a human friendly way - any ideas??
 - Does `$locale` do anything other than language? If so it's still possible to get the locale the same, but provide alternative translations. It's a lot messier though...

## The code

    class SH_Pick_Lang{
    	/**
    	 * A unique name for this plug-in
    	 */
    	static $name ='sh_pick_lang';
    	
    	/**
    	 * Hook the functions
    	 */
    	public function __construct(){
    	
    		if( isset($_POST[self::$name]) ){
    			add_action('locale',array($this,'update_user'));
    		}
    		add_filter( 'locale', 'wpse35622_get_new_locale',20 );
    		add_action( 'wp_before_admin_bar_render', array( $this, 'admin_bar') );
    	}
    	
    	/**
    	 * Update the user's option just in time! Only once mind...
    	 */
    	function update_user($locale){
    		$save_locale = $_POST[self::$name];
    		update_user_meta(get_current_user_id(), 'wpse_locale', $save_locale);
    		remove_filter(current_filter(),__FUNCTION__);
    		return $locale;
    	}
    	
    	/**
    	 * Add a really horrible looking dropdown menu that I'm sure Kaiser will make look fantastic.
    	 */
    	function admin_bar(){
    		global $wp_admin_bar;
    
    		$wp_admin_bar->add_menu( array(
    			'id'        => 'shlangpick',
    			'title'     => $this->wpse_language_dropown(),
    		) );
    	}
    	
    	/**
    	 * Generates a list of available locales.
    	 * Searches the wp-content/languages folder for files of the form xx_xx.mo
    	 * 
    	 * TODO Not all locales are of the form xx_xx.mo - we might miss some.
    	 * TODO Better way of gettin gthe wp-content/languages folder without a constant?
    	 */
    	function wpse_language_dropown(){
    		$name = self::$name;
    		$locale = get_locale();
    		
    		$files = glob(WP_LANG_DIR.'/??_??.mo');
    		$langs=array('en_US');
    		
    		foreach ($files as $file){
    			$langs[]=basename($file,'.mo');
    		}
    		
    		$html = "<form method='post'> ";
    		$html .= "<select name='{$name}'>";
    			foreach($langs as $lang){
    				$html .= "<option ".selected( $lang, $locale, false)." value='{$lang}'>{$lang}</option>";
    			}
    		$html .= "</select>";
    		$html .= get_submit_button('Change Language','secondary', 'submit', true);
    		$html .= "</form >";
    		
    		return $html;
    	}
    
    } // END Class
    
    //Initiate...
    $sh_pick_lang = new SH_Pick_Lang();

  [1]: http://queryposts.com/function/get_locale/